this provides an elegant way of implicitly 'passing along' an object reference, leading to cleaner API design and easier reuse.
There are two meanings often assumed, but both are wrong:
-
thisequals the function itself. -
thisequals the function's scope.
this is actually a binding that is made when a function is invoked. What it references is determined entirely by the call-site where the function is called.
The four rules of this
Default Binding
this is the default rule when none of the other rules apply.
function ball(){
console.log(this.a);
}
var a = 3;
ball(); //3
Implicit Binding
Here, the call-site uses the obj context to reference the function.
function ball(){
console.log(this.a);
}
var obj = {
a: 3,
ball: ball
};
obj.ball(); //3
Explicit Binding
ball.call() allows us to force its this to be the obj.
function ball(){
console.log(this.a);
}
var obj = {
a: 3,
};
ball.call(obj); //3
new Binding
By calling ball() with new in front of it, we have constructed a new object and set that new object as the this for the call of ball().
function ball(a){
this.a = a;
}
var bar = new ball(2);
console.log(bar.a); //2
Order of precedence
- Called with
new? Use the newly constructed object. - Called with
callorapply? Use the specified object. - Called with a context object? Use the context object.
- Default binding; if 'strict mode' => undefined.
Arrow Functions
Arrow functions are signified not by the function keyword, but by the so-called "fat-arrow" operator =>. Instead of using the four rules, arrow-functions adopt the this binding from the enclosing scope.
function ball(){
//return an arrow-function
return(a) => {
//'this' here is lexically inherited from 'foo()'
console.log(this.a);
};
}
var obj1 = {
a: 2,
};
var obj2 = {
a: 4,
};
var baz = ball.call(obj1);
baz.call(obj2); //2, not 4
the arrow-function created in ball() captures whatever ball()s this is at its call-time. ball() was this bound to obj1, so baz will be this bound to obj1 as well.
Top comments (0)