一、This的核心绑定机制(高频考点)
1. 全局作用域
- 指向:全局对象(浏览器中为
window,严格模式下为undefined)。 - 示例:
console.log(this); // 浏览器中输出Window对象 function test() { console.log(this); // 非严格模式:Window;严格模式:undefined }
2. 函数调用
- 指向:调用该函数的对象,或全局对象(严格模式下为
undefined)。 - 示例:
const obj = { name: 'Alice', sayHi() { console.log(this.name); // 指向obj,输出"Alice" } }; obj.sayHi(); // 隐式绑定:this指向obj
3. 构造函数
- 指向:新创建的实例对象。
- 示例:
function Person(name) { this.name = name; // this指向新创建的Person实例 } const p = new Person('Bob'); console.log(p.name); // 输出"Bob"
4. 显式绑定
- 方法:
call()、apply()、bind()强制指定this。 - 示例:
function greet() { console.log(`Hello, ${this.name}`); } const user = { name: 'Charlie' }; greet.call(user); // 输出"Hello, Charlie"
二、应用场景(结合项目经验)
-
对象方法:访问对象自身属性。
const calculator = { value: 0, add(num) { this.value += num; // this指向calculator return this; // 支持链式调用 } }; calculator.add(5).add(3); // value变为8 -
事件处理:获取触发事件的DOM元素。
<button onclick="this.style.color='red'">点击变红</button> -
构造函数:初始化实例属性。
class Car { constructor(model) { this.model = model; // this指向新Car实例 } }
三、常见易错点(高频陷阱)
1. 回调函数中的this丢失
- 问题:回调函数的this默认指向全局对象(非严格模式)。
- 示例:
const timer = { seconds: 10, start() { setTimeout(function() { console.log(this.seconds); // 错误:this指向window,而非timer }, 1000); } }; - 解决方案:
// 1. 使用箭头函数(不绑定this,继承外层this) setTimeout(() => { console.log(this.seconds); // 正确:this指向timer }, 1000); // 2. 保存this引用(var that = this) const that = this; setTimeout(function() { console.log(that.seconds); // 正确 }, 1000);
2. DOM事件中的this
- 问题:事件处理函数的this指向触发事件的元素,而非定义该函数的对象。
- 示例:
const button = document.querySelector('button'); const obj = { handleClick() { console.log(this); // 指向button元素,而非obj } }; button.addEventListener('click', obj.handleClick); - 解决方案:
// 1. 使用箭头函数 button.addEventListener('click', () => obj.handleClick()); // 2. bind方法 button.addEventListener('click', obj.handleClick.bind(obj));
四、ES6箭头函数的this(高频考点)
1. 核心区别
- 箭头函数:不绑定this,继承外层(函数或全局)作用域的this值。
- 普通函数:根据调用方式动态绑定this。
2. 示例对比
const obj = {
name: 'Alice',
normal() {
console.log(this.name); // 指向obj
},
arrow: () => {
console.log(this.name); // 指向window(全局作用域)
}
};
obj.normal(); // 输出"Alice"
obj.arrow(); // 输出undefined(window.name为空)
3. 适用场景
- 回调函数:避免this丢失(如定时器、数组方法)。
const numbers = [1, 2, 3]; numbers.forEach((num) => { console.log(this); // 继承自外层作用域 }); - 不适合场景:
- 对象方法(需动态this);
- 构造函数(无法使用new调用)。
五、总结
“This对象在JavaScript中是动态绑定的,其指向取决于函数的调用方式:
- 全局作用域:指向全局对象(严格模式下为undefined);
- 函数调用:指向调用者对象(或全局对象);
- 构造函数:指向新创建的实例;
- 显式绑定:通过call/apply/bind强制指定this;
- 箭头函数:继承外层作用域的this,不动态绑定。
在实际项目中,注意箭头函数和普通函数的适用场景,通过显式绑定或箭头函数解决this丢失问题,并在严格模式下编写代码以避免全局对象污染。”,