Skip to main content

ECMAScript this

在 ECMAScript 中,this 提供了一种更优雅的方式来隐式传递一个对象引用,可以将 API 设计得更加简洁并且易于复用。

this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式

按照绑定的优先级排序

new 绑定

如果函数在 new 中调用,则 this 绑定的是新创建的对象。

function foo(a) { 
this.a = a;
}

var bar = new foo(1);
console.log(bar.a); // 输出:1

显式绑定

如果函数通过 call、apply 调用,则 this 绑定的是指定的对象。

function foo() { 
console.log(this.a);
}
var obj = {
a:1
};

foo.call(obj); // 输出:1

如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply、bind,这些值在调用时会被忽略。

function foo() { 
console.log(this.a);
}
var a = 1;

foo.call(null); // 输出:1

隐式绑定

如果函数在某个上下文对象中调用,则 this 绑定的是那个上下文的对象。

function foo() { 
console.log(this.a);
}
var obj2 = {
a: 2,
foo: foo
};
var obj1 = {
a: 1,
obj2: obj2
};

obj1.obj2.foo(); // 输出:2

如果函数的调用方式发生改变,就会导致隐式丢失(被隐式绑定的函数丢失绑定对象),结果是默认绑定。

function foo() { 
console.log( this.a );
}
var obj = {
a: 1,
foo: foo
};
var a = 2;

var bar = obj.foo;
bar(); // 输出:2

setTimeout(obj.foo, 100); // 输出:2

默认绑定

如果都不是,使用默认绑定。只有运行在非严格下时,默认绑定才能绑定到全局对象,否则会绑定到 undefined。

function foo() { 
console.log(this.a);
}
var a = 1;

foo(); // 输出:1

规则例外:箭头函数的绑定

箭头函数不使用 this 的四种标准规则,而是根据当前的词法作用域来决定 this 的绑定。

具体来说,箭头函数会继承外层函数调用的 this 绑定,这其实和 ES6 之前代码中的 self = this 机制一样。

var foo = () => { 
console.log(this.a);
}
var obj = {
a: 1
};
var a = 2;

foo.call(obj); // 输出:2