this is one of most mystery feature in JavaScript, after assigning the object method to other variable, the binding (this keyword) is lost
var john = {
name: 'John',
greet: function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
};
john.greet("Mark"); // Hi Mark, my name is John
var fx = john.greet;
fx("Mark"); // Hi Mark, my name is
my question is:
1) what is happening behind the assignment? var fx = john.greet; is this copy by value or copy by reference? fx and john.greet point to two diferent function, right?
2) since fx is a global method, the scope chain contains only global object. what is the value of this property in Variable object?
bind() The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
Binding something in JavaScript means recording that identifier in a specific Environment Record . Each Environment Record is related to a specific Execution Context - and that binds the identifier (variable or function name) to the this keyword for that execution context.
Using the typeof Operator In JavaScript, the typeof operator is useful to check the type of the variable, function, objects, etc. When we use the function name as the operand of the typeof variable, it returns the 'function' string, and we can check whether the function is defined.
john.greet("Mark")
actually calls a function. When you do var fx = john.greet;
, you're getting a reference to the function. So when you call it, this
is not bound to john
. What you're actually doing is window.fx("Mark")
and so this
is the window
object. You were on the right track when you said that it was in the global context. In this particular instance, the global object is window
, and so fx
is actually window.fx
.
When you have a function reference you should use call
or apply
if you want to set the value of this
. Try doing this:
fx.call(john, "Mark");
The first argument in call
or apply
is the value used for this
in the context of the function call.
EDIT
Some people mentioned that the real issue here might be confusion surrounding an object literal vs. an instance of an object. You're creating an object literal which also behaves kind of like a singleton. You cannot create a new instance of that object. In this case john
is a reference to that object literal. In that context, this
in the function greet
refers to the object literal itself. Hence when you call john.greet("Mark")
, this
is bound to john
.
When you grab a reference to john.greet
just by itself and assigning it to a global variable, you're essentially doing this:
var fx = function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
In this scenario, this
is window
, because fx
is basically window.fx
(since the global object here is window
. Assuming this code was wrapped inside another function, then the global object would refer to that function.
If you want to create multiple instances of an object, you can do something like this:
var Person = function(name) {
var self = this; //maintains a reference to the instance
this.name = name;
this.greet = function(name) {
alert("Hi " + name + ", my name is " + self.name);
}
}
var john = new Person("John");
john.greet("Mark"); // alerts "Hi Mark, my name is John"
var fx = john.greet;
fx("Mark"); // also alerts "Hi Mark, my name is John"
Here, the self
variable (which is local to the function) maintains a reference to the actual instance because you're binding it to this
when you create the object.
There are many best practices associated with OOP in Javascript. You can Google and find out (there are many links). I recommend reading stuff from Douglas Crockford especially.
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