JS: this
- 全局环境下的 this
- 上下文对象调用中的 this
- apply/bind/call (abc) 改变 this 指向
const d = {
// settimeout 一般默认使用箭头函数, 保证自己是一个纯函数, 不受到 settimeout this 的影响
log() {
setTimeout(() => {
console.log(this, 'd');
}, 1000);
},
// nodejs 指向 timeout, 浏览器中指向全局 Window 对象
// settimout 调用的内部函数, 方法所在的函数, 自然就指向了 settimeout
logWithoutThis() {
setTimeout(function () {
console.log('global', this);
}, 1000);
}
};
function test() {
// 严格模式下, this 指向 undeined, 否则 this 指向全局对象 global
'use strict';
console.log('test', this);
}
const foo = {
bar: 10,
// 等价于 fn() { ... }
fn: function() {
console.log(this)
console.log(this.bar)
}
}
// 这里 this 仍然指向的是 window。虽然 fn 函数在 foo 对象中作为方法被引用,但是在赋值给 fn1 之后,fn1 的执行仍然是在 window 的全局环境中。
var fn1 = foo.fn // "裸奔"
fn1()
// 指向 foo, fn 其实就是一个函数.
foo.fn()
d.log()
d.logWithoutThis();
const o1 = {
text: 'o1',
fn: function() {
return this.text
}
}
const o2 = {
text: 'o2',
// 如果希望挂在到 o2, fn: o1.fn 赋值
fn: function (test) {
console.log(test)
return o1.fn();
// abc 改变 this 指向
// return o1.fn.apply(o2, ['banana']);
// return o1.fn.bind(o2)();
}
}
const o3 = {
text: 'o3',
fn: function() {
var fn = o1.fn
return fn()
}
}
console.log(o1.fn()) // o1
console.log(o2.fn()) // o1
console.log(o3.fn()) // undefined
-
Function.prototype.apply()
按照数组传递函数参数,call 则是逐个调用函数参数,bind 的参数是在绑定时传入的 -
ac 直接改变函数,b 是创建了一个新的绑定函数,ac 的区别主要是传递的函数参数上.
-
如果将对象的方法单独抽离出来 (比如结构,或者重新赋值), this 指向就会发生变化
const x = 9;
const moduleX = {
x: 99,
getX() {
console.log(this.x, this);
}
};
const { getX } = moduleX;
// wrong
getX();
// correct
getX.apply(moduleX);