1. this
是什么?
在 JavaScript 中,this
关键字用于指向调用它的对象。但它的指向并不是在编写代码时确定的,而是在 函数执行时 决定的。
2. this
在不同场景下的表现
2.1 作为对象的方法调用
javascript
const obj = {
name: 'Tom',
sayHello() {
console.log(this.name);
}
};
obj.sayHello(); // Tom
解析 : this
指向 obj
,因为 sayHello
是通过 obj
调用的。
2.2 直接调用函数(普通函数调用)
scss
function show() {
console.log(this);
}
show(); // 非严格模式下:window / 严格模式下:undefined
解析:
- 在非严格模式 下,
this
指向全局对象window
。 - 在严格模式 下,
this
为undefined
。
2.3 构造函数调用
ini
function Person(name) {
this.name = name;
}
const p = new Person('Tom');
console.log(p.name); // Tom
解析 : this
指向新创建的实例 p
。
2.4 箭头函数中的 this
javascript
const obj = {
name: 'Tom',
sayHello: () => {
console.log(this.name);
}
};
obj.sayHello(); // undefined
解析:
- 箭头函数不会创建自己的
this
,它的this
继承自定义它的作用域。 - 这里
this
指向的是全局对象window
(在严格模式下undefined
)。
正确写法(使用普通函数):
javascript
const obj = {
name: 'Tom',
sayHello() {
console.log(this.name);
}
};
obj.sayHello(); // Tom
2.5 this
丢失问题
javascript
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(this.name);
}
}
const p = new Person('Tom');
const x = p.sayHello;
x(); // undefined
原因 : p.sayHello
只是一个函数的引用 ,它被赋值给变量 x
,但 x
和 p
没有任何关系了 。 在 JavaScript 中,this
只在函数被调用时确定,而不是在函数定义时。
所以这里this
指向 window
(非严格模式)或 undefined
(严格模式),
解决方案:
-
使用
bind
绑定this
iniconst x = p.sayHello.bind(p); x(); // Tom
-
使用箭头函数 (继承
this
)scssconst x = () => p.sayHello(); x(); // Tom
-
使用
call
或apply
scssx.call(p); // Tom x.apply(p); // Tom
3. this
在事件处理程序中
javascript
document.querySelector("button").addEventListener("click", function() {
console.log(this); // this 指向被点击的 button 元素
});
注意 :如果使用箭头函数,this
可能会指向 window
而不是按钮。
javascript
document.querySelector("button").addEventListener("click", () => {
console.log(this); // this 指向 window,而不是按钮
});
解决方案:用普通函数代替箭头函数。
4. this
在 setTimeout
和 setInterval
中
javascript
const obj = {
name: 'Tom',
sayHello() {
setTimeout(function() {
console.log(this.name);
}, 1000);
}
};
obj.sayHello(); // undefined
原因 :setTimeout
里的 this
指向 window
(非严格模式)。
解决方案:
-
使用箭头函数 (继承
this
)javascriptsayHello() { setTimeout(() => { console.log(this.name); }, 1000); }
5. this
在 call
、apply
和 bind
中
call
和 apply
(手动绑定 this
并立即执行)
arduino
function sayHello() {
console.log(this.name);
}
const person = { name: 'Tom' };
sayHello.call(person); // Tom
sayHello.apply(person); // Tom
区别:
call(thisArg, arg1, arg2, ...)
直接传参数。apply(thisArg, [arg1, arg2, ...])
以数组方式传参数。
bind
(手动绑定 this
,但不会立即执行)
ini
const boundFunc = sayHello.bind(person);
boundFunc(); // Tom
6. 总结
场景 | this 指向 |
---|---|
对象方法调用 | 调用它的对象 |
普通函数调用 | window (非严格模式)或 undefined (严格模式) |
构造函数调用 | 新创建的实例 |
箭头函数 | 继承外层作用域的 this |
事件处理程序 | 绑定的 DOM 元素(普通函数)或 window (箭头函数) |
setTimeout/setInterval |
window (非严格模式)或 undefined (严格模式) |
call/apply/bind |
绑定的对象 |
注意
- 箭头函数不会创建自己的
this
,它会继承定义它的作用域的this
。 - 普通函数的
this
取决于调用方式,而不是定义位置。 - 手动绑定
this
可以用bind
,call
,apply
。