I have this code:
var foo = {
x: 2,
bar: function() {
alert(this.x);
}
};
Why does foo.bar()
alert 2
while [foo.bar][0]()
alerts undefined
?
So, technically [foo.bar][0]
is equivalent to foo.bar
, but at the point of calling the function bar
has lost the "lexical binding" with the foo
object, so when you call it, JavaScript actually executes the following:
foo.bar.call([foo.bar]);
Generally, this expression:
XXX.yyy(args)
Is interpreted as:
XXX.yyy.call(XXX, args);
In this case XXX
is [foo.bar]
and .yyy
is [0]
.
To fix it, you need to explicitly bind foo
again:
[foo.bar][0].call(foo);
when you do [foo.bar][0]()
, this
in the bar
is [foo.bar]
, the array but not the object foo
.
Just imaging that the method name is the number 0
(although that is wrong syntax).
([foo.bar]).0(); // you see, `this` became the array object: [foo.bar]
And [foo.bar].x
is undefined
.
Its because you are invoking the function on the array object. The "this" keyword is equal to the array.
[foo.bar][0]();
In javascript the context in which a function is invoked can vary. The "this" keyword can have different values based on how it was invoked. If a function is invoked on an object (including arrays), the language will make "this" equal to the object that it was called on. On the other hand you can save the function of another object into another variable and invoke it. Like you did with this:
var test=[foo.bar][0];
test();`//here is alert "2"
and the context will be the window.
Research the call and apply methods in javascript. This will open you eyes on how flexible the "this" keyword is. This is a place of much confusion among many programmers coming from other languages, but once this principle is understood there is a lot of power that comes from it. JQuery for example uses "call" and "apply" to have the callbacks of events invoked in the context of the element that the event was fired on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With