Member undefined when calling function indirectly [duplicate] - javascript

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 2 years ago.
class Hello{
constructor(member) {
this.member = member;
this.name_function_map = {"print_member" : this.print_member};
}
print_member(){
console.log(this.member);
}
}
let h = new Hello(2);
h.print_member();
//=> works as expected
h.name_function_map["print_member"]();
//=> why is it h. member undefined
the output is:
2
undefined
can someone please enlighten me, why is calling the member function of Hello through a reference stored in a map any different than calling it directly?
And how may i work around that.

When you execute:
let h = new Hello(2);
h.print_member();
The this keyword inside the print_member method will be equal to h (the object instance). That is correct. But, when you execute:
h.name_function_map["print_member"]();
or equally
h.name_function_map.print_member();
the this keyword inside the print_member method will be equal to h.name_function_map, which is:
{"print_member" : this.print_member}
Obviously, this object does not have a member property, and that's why you are getting undefined.

Related

Why do I need to bind a shadowed function that is called through the same object? [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 4 years ago.
Was doing some dirty things to Array.prototype when I ran into this:
Array.prototype.hook_pop = function(callback) {
var base_pop = this.pop.bind(this); //<-- this works
var base_pop = this.pop; //<-- this doesn't work
this.pop = function() {
var ret = base_pop();
callback(ret, this);
return ret;
}
}
Initially I tried using the non-working option and got an error "Uncaught TypeError: Cannot convert undefined or null to object".
The way I've understood it, unless otherwise bound, "this" should point to the object through which the method is called from, in this case the array instance. When called on the same object though, either way, "this" should be the same when being passed to the pop function, whether its bound or not. Why doesn't the second option work?
var ret = base_pop();
In this line you're invoking base_pop() by itself, and not as a method of any object. Because of this, its this value isn't set.

how object.constructor() works? [duplicate]

This question already has answers here:
Javascript constructor return values [duplicate]
(2 answers)
Closed 5 years ago.
Recently I have attended one interview, Interviewer asked one interesting question have a look
function MyClass(){
this.a = 10;
return 20; // Interesting part
}
var obj1 = new MyClass();
console.log(obj1.a); // 10 works as expected.
console.log(obj1.constructor()); // 20 later I found this
how will you access return value(20) from obj1?
I found the answer after looking proto of the obj1.
obj1.constructor() Works as expected
Please help me to understand this.
See mdn:
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
The 20 goes nowhere and cannot be accessed. It isn't an object, so the instance of MyCass is returned instead.

Lexical `this` and Timeout [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 5 years ago.
Im reading through the YDKJS books and I thought I understood lexical this for the most part.
However there is a section with code that shows this:
var obj = {
id: "awesome",
cool: function coolFn() {
console.log( this.id );
}
};
var id = "not awesome";
obj.cool(); // awesome
setTimeout( obj.cool, 100 ); // not awesome
Ok so the first obj.cool() makes sense of course....but why is the setTimeout printing not awesome.....I mean it's still calling obj.cool() which this refers to it's own objects id?
Or does setTimeout get called as another function that calls obj.cool()? but even in that case (Which I tried calling obj.cool() inside another function that also had an id property and it still printed the right one......so why would the this change with setTimeout?
Since the OBJ.COOL function is passed by reference, you are not actually passing the context object with it. The function gets new invocation context and executes on the WINDOW object, which now has a property called ID which was defined earlier.

String passed as function parameter is undefined [duplicate]

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 6 years ago.
When I pass a string to a function as a parameter, it returns undefined. Why is that?
let a = 'b';
let test = (a) => console.log(a);
test(); // undefined
When you call test(); you aren't putting anything between ( and ), so you aren't passing any parameters.
When you defined test (with (a) =>) you created a local variable a that masks the global variable with the same name.
To pass a you have to actually pass it: test(a).
Why is that?
Because you don't pass any argument. Try the following:
test(a);
The following definition:
let test = (a) => console.log(a);
is like the following:
function test(a){
console.log(a);
}
So when you call test, without passing any argument the value of a would be undefined.

Why does `this` refers to `o` here (o.method)() instead of a global object [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
Suppose I have an object:
var o = {
prop: 3,
method: function() {return this.prop}
}
I was expecting this
(o.method)()
to return undefined, however it returned 3 meaning that this is set to o inside method. Why is it so? If you evaluate (o.method) separately, it evaluates to a standalone function, so I expected this to reference global object. Why, for example, the difference exists here:
(o.method)() vs (o.method || true)()
I know that o.method() will use o as context, the question is specifically about accessing the function first like this (o.method) and then calling it.
That's just how JavaScript's rules work. Unless you do some contortions, this usually means the thing before the . when you access the method prior to calling it. In this case, that's o.
The following statements are identical:
(o.method)();
o.method();
o.method.call(o);
o["method"]();
However, if you put the method on something else, it'll take on the meaning of the thing it's on:
var p = {prop: 42, method: o.method};
p.method(); // returns 42
var method = o.method;
var prop = 13;
method(); // returns 13
Note: As JavaScript grew to be much more than it was originally designed for, people realized that this probably wasn't the most intuitive way for this to work, so in ES6 if you use "Arrow Functions" (aka Lambda Functions) it won't rebind this.

Categories