mdn
my git
this由调用方法与位置决定,与定义位置,作用域,上下文均无关
全局
绑定到全局对象
this // window
console.log(this) // window
函数调用
简单调用
绑定到全局
function f() {
console.log(this);
}
f(); // window
严格模式会绑定到undefined
// strict mode下绑定
function f() {
'use strict'; // 只有在调用的运行中使用strict mode才会绑定到undefined
console.log(this.a);
}
var a = 2;
(function () {
f();
})(); // TypeError
'use strict'
function f() {
console.log(this.a);
}
var a = 2;
(function () {
'use strict'
f();
})(); // 2
使用apply,call,bind
是一种显式绑定
function f() { console.log(this); }
f.apply(obj); // obj
f.call(obj); // obj
var f1 = f.bind(obj); // f1 is a function which is always bind to obj
f1(); // obj
通过call与apply绑定后的函数无法重新绑定(硬绑定)
function f() {
console.log(this.a);
}
var obj = { a: 1 };
function f1() {
f.call(obj);
}
var a = 2;
f1.call(window); // 1
var f2 = f1.bind(obj);
f2 = f1.bind(window);
f2(); // 1
箭头表达式
无自己的this,参考
绑定到外层的this,之后无法通过硬绑定重新绑定
var obj = {
a: function () {
return (() => console.log(this));
}
}
obj.a()(); // obj
var f = obj.a();
f(); // obj 在obj的调用过程中外层this绑定了!
var f2 = obj.a;
f2()(); // window
对象调用
var obj = {
func: function f() { console.log(this) }
}
obj.func() // obj
严格意义上方法f不属于对象,只是由对象调用,从而将其this绑定到对象,因此可能会发生丢失
(obj.func)() // obj
var c;
(c = obj.func)() // window
(obj.func = obj.func)() // window
// callback
var obj = {
f() {
console.log(this);
}
}
function f(fn) {
fn(); // same as (fn = obj.f)()
}
f(obj.f); // windows
构造调用
this指向返回到新对象
调用过程参考
var NewObj = function() {}
var Obj = new NewObj(); // this == Obj
优先级
new(构造调用) > 硬绑定(call,apply,bind) > 隐绑定(对象调用) > 默认(window)
例外
硬绑定中传入null或undefined会应用默认绑定
function f() { console.log(this) } var f1 = f.bind(null); var f2 = f.bind(); f1() // window f2() // window f.apply() // window f.call(null) // window
- 函数不是对象的成员,只是一个引用,因此用对象赋值会使用默认绑定
其他
map
map可将this传递到函数中,若不传递,默认为window
var obj = {
array: [1],
f() {
this.array.map(function (item) {
console.log(this);
});
},
f1() {
this.array.map(function (item) {
console.log(this);
},this);
}
};
obj.f(); // window
obj.f1(); // obj