理解js中的this

this是javascript中的关键字,this在运行的时候决定而不是在作者编写函数(author-time)的时候决定

因此理解this的最好方式查看调用栈(call stack),找到调用位置(call-site),就总体而言this指向的是调用该函数的对象。

四种情况:

一、默认绑定(default binding)--作为函数调用

再次明确, this指向的是调用该函数的对象 。下面的函数foo在调用的时候实际上相当于global.foo(),这里global是window对象,this.a指的是window对象中定义的a,而不是函数foo内部定义的a,因 此输出值为2而不是3.
function foo() {
     var a = 3;
     console.log( this.a );
}
var a = 2;
foo(); // 2
二、隐式绑定(Implicit Binding)---作为对象属性
既然作为对象的属性,自然也就是该对象调用该函数,this指向这里的obj。
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2,
    foo: foo
};
var a = 3;
obj.foo(); // 2

这里值得注意的是this的隐式丢失( Implicitly lost)问题
下面的bar变成了一个foo函数指针,在调用的时候相当于global.bar()
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2,
    foo: foo
};
var bar = obj.foo; // 变成普通的函数调用
var a = 3; // "a"是global对象的一个属性。
bar()//3
如果存在一个对象链条呢?看最近的那个调用对象
function foo() {
    console.log( this.a );
}
var obj2 = {
    a: 42,
    foo: foo
};
var obj1 = {
    a: 2,
    obj2: obj2
};
obj1.obj2.foo(); // 42
三、显式绑定(Explicit Binding)---call和apply
这里指的是用call和apply来强制绑定调用对象。
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2
};
foo.call( obj ); // 2
书中还提到一种hard-binding,顾名思义,就是直接把把函数调用对象直接绑死了,使得在运行的难以修改,根据上面的“就近原则”,obj永远是最近的那个调用对象,bar.call(window)相当于window.obj.foo()。
function foo() {
    console.log( this.a );
}
var obj = {
    a: 2
};
var bar = function() {
    foo.call( obj );
};
bar(); // 2
setTimeout( bar, 100 ); // 2
// hard-bound `bar` can no longer have its `this` overridden
bar.call( window ); // 2

四、创建对象绑定(new Binding)----new创建新对象
用new创建对象,this指向的是新创建出来的对象。
function Foo(name){
   this.name = name;
}
var a = new Foo("Allen");
a.name;//"Allen"

你可能感兴趣的:(javascript)