I have a class testClass and in testClass there is a getter called testGetter and a public object called testObject. In testObject I have a function nestedFunction which attempts to call testGetter but cannot as the scope for this is in the testObject. How could I call the getter (or any function) from the object?
class testClass {
get testGetter() {
return "test"
}
testObject = {
nestedFunction : function(){
console.log(this)
return this.testGetter
}
}
constructor()
{
console.log(this.testObject.nestedFunction())
}
}
new testClass()
Output:
{ nestedFunction: [Function: nestedFunction] }
undefined
Classic use case of arrow functions.
class testClass {
get testGetter() {
return "test"
}
testObject = {
nestedFunction: () => {
console.log(this)
return this.testGetter
}
}
constructor() {
console.log(this.testObject.nestedFunction())
}
}
new testClass()
Related
I don't understand the error in the code below. I tried calling another class's function from another class. But I gives the error error: Uncaught TypeError: Cannot read property '_name' of undefined
class Person {
constructor() {
this._name = "Name-Person";
}
getName() {
return this._name;
}
}
class Test1 {
constructor() {
let p = new Person();
new Test2(p.getName);
}
}
class Test2 {
constructor(getName) {
console.log(getName());
}
}
new Test1()
How can I fix the error?
When passing the function to Test2 you need to bind p to the function
new Test2(p.getName.bind(p));
class Person {
constructor() {
this._name = "Name-Person";
}
getName() {
return this._name;
}
}
class Test1 {
constructor() {
let p = new Person();
new Test2(p.getName.bind(p));
}
}
class Test2 {
constructor(getName) {
console.log(getName());
}
}
new Test1()
you can use public class field:
class Person {
constructor() {
this._name = "Name-Person";
}
getName = () => {
return this._name;
}
}
class Test1 {
constructor() {
let p = new Person();
new Test2(p.getName);
}
}
class Test2 {
constructor(getName) {
console.log(getName());
}
}
new Test1()
Because you are passing the function and not the entire class or its value, _name does not exist in the context of the Test2 constructor.
A couple of simple solutions is to either pass in the result of getName() to the constructor, or the entire class of Person.
new Test2(p); // And in Test2 use p.getName()
// or
new Test2(p.getName()); // And in Test2 use the result
I have this code snipet:
proxy('http://my-custom-api-endpoint.com', {
proxyReqOptDecorator(options) {
options.headers['x-forwarded-host'] = 'localhost:3000'
return options
}
})
It is a call to a function named proxy, the first argument is a string, but the second argument has a syntax than I can't recognize:
{
functionName(args) {
// statements
}
}
Can someone explain that syntax please?
Its a shorthand method in Object Initializer to create a property whose value is a function.
// Shorthand method names (ES2015)
let o = {
property(parameters) {}
}
//Before
let o = {
property: function(parameters) {}
}
This syntax is also sued in classes to declare class methods.
class Animal {
speak() {
return this;
}
static eat() {
return this;
}
}class Animal {
speak() {
return this;
}
eat() {
return this;
}
}
Good day,
I dont know if am can explain this well for you to help but i will like to use a an ES6 class to create an object that can be called like this.
var = varaibles
obj = objects
obj.var
obj.var.method
obj.var.var.method
obj.method.var
and so on.
I can only do one step
obj.var && obj.method
i will kind appreciate if one can help me here thanks
this is what i have done
class Table extends someClass {
constructor() {
super();
this.column = {
sort: () => {
console.log("firing");
},
resize: () => {
console.log("firing");
}
};
this.cells = {
edit: () => {
console.log("firing");
}
};
}
myMethods() {
//BLAH
}
}
From what I understood, here is my solution.
If I return a object full of methods, I can use that object as I like.
class someClass {
// this is a parent method
Parent() {
console.log(`From a Parent`)
}
// a getter that returns an object
get parentWithChild() {
return {
child() {
console.log(`From a Child`)
}
}
}
// a function that returns an object
Methods() {
return {
child() {
console.log(`From a Child`)
}
}
}
}
const cool = new someClass();
cool.Parent(); // From a Parent
cool.parentWithChild.child(); // From a Child
cool.Methods().child(); // From a Child
You can use similar pattern on the extended class too.
I want to inherit a function with proxied constructor, like SubB below;
const Base = function () {};
Base.prototype.baseMethod = function () { return 'base method'; }
class SubA extends (new Proxy(Base, {})) {
subMethod () { return 'sub method'; }
}
const handler = { construct: (target, args) => new target(...args) };
class SubB extends (new Proxy(Base, handler)) {
subMethod () { return 'sub method'; }
}
However, it does not work collectly; Subclass methods seems not to be bound in SubB.
(new SubA()).baseMethod(); //=> "base method"
(new SubB()).baseMethod(); //=> "base method"
(new SubA()).subMethod(); //=> "sub method"
(new SubB()).subMethod();
//=> Uncaught TypeError: (intermediate value).subMethod is not a function
What's happening in class SubB and how can I fix it (or is it possible)?
You are ignoring new.target, which is why the instance that your proxied constructor creates always inherits from the Base (the target in the proxy handler) only, and not from the SubB.
You should use Reflect.construct as the default action of the construct trap:
const handler = {
construct(target, args, newTarget) {
return Reflect.construct(target, args, newTarget);
}
};
class SubB extends (new Proxy(Base, handler)) {
subMethod () { return 'sub method'; }
}
I want to keep this in class methods.
I can use arrow functions, but I want to override some methods in extended class.
Now I have this solution and it works:
class Foo {
bar = "Context preserved.";
constructor() {
this.foo = this.foo.bind(this);
}
foo() {
alert(this.bar);
}
}
class Foo2 extends Foo {
foo() {
alert(this.bar + " Class extended");
}
}
class Bar {
bar = "Context lost.";
}
let foo = new Foo2();
let bar = new Bar();
foo.foo.apply(bar); // Context preserved. Class extended
Is it a good practice to do it such way? If it is, is there some keyword in typescript to do it automatically?
like
class Foo() {
public conserved foo() { }
}
which generates:
var Foo = (function () {
function Foo() {
this.foo = this.foo.bind(this);
}
Foo.prototype.foo = function () { };
return Foo;
}());
It's a valid practice and it's being used.
I'm unaware of a way to tell typescript to do this automatically, but you can search the issues for something like it.
You can have a decorator that does that for you, for example:
function construct(constructor: Function, methods: string[], args: any[]) {
var c: any = function () {
return constructor.apply(this, args);
}
c.prototype = constructor.prototype;
let instance = new c();
methods.forEach(name => {
instance[name] = instance[name].bind(instance);
});
return instance;
}
function BindMethods(constructor: Function) {
const methods = [] as string[];
Object.keys(constructor.prototype).forEach(name => {
if (typeof constructor.prototype[name] === "function") {
methods.push(name);
}
});
return (...args: any[]) => {
return construct(constructor, methods, args);
};
}
#BindMethods
class Foo {
bar = "Context preserved.";
foo() {
console.log(this.bar);
}
}
let foo = new Foo();
setTimeout(foo.foo, 10);
(code in playground)
I tested it with this simple use case and it worked just fine.