前言
this指针是JavaScript中非常重要但容易引起混淆的概念。本文将详细解释this指针的用法和原理,改变this指向的三个常用的函数方法,帮助读者更好地理解和使用this指针。
关于this对象
全局上下文中的this
this对象是在运行时基于函数的执行环境绑定的,在全局环境中,this指向全局对象,在浏览器中是window,node中是global。
console.log(this); // 在浏览器中输出 window 对象,在 Node.js中输出 global 对象
函数中的this
普通函数的this指向
非严格模式下,普通函数被调用时,因为全局的方法和属性都是window对象的方法和属性,所以this指向全局对象(浏览器中的window),严格模式下,this的值是undefined。
function foo() {
console.log(this);
}
foo(); // 在非严格模式下输出 window 对象,在严格模式下输出 undefined
对象的方法中的this指向
当函数作为对象的方法调用时,this指向该对象。
const obj = {
name: 'Alice',
sayHello: function() {
console.log(this.name);
}
};
obj.sayHello(); // 输出 'Alice'
this指向obj对象,因此this.name指向obj对象的name属性。
修改一下
const obj = {
name: 'Alice',
sayHello: function() {
console.log(this.name);//Alice
function test(){
console.log(this);//window,因为是独立调用的函数
}
test();
}
};
obj.sayHello(); // 输出 'Alice'
test函数的this指向window对象,因为它是独立调用的函数。
构造函数中的this指向
当函数作为构造函数调用时,this指向新创建的对象。(函数通过new关键字调用,this指向新创建的实例对象)
function Person(name) {
this.name = name;
}
const person = new Person('Bob');
console.log(person.name); // 输出 'Bob'
箭头函数中的this
首先,箭头函数没有自己的this,全局作用域下,箭头函数的this指向全局对象,而在对象的方法中使用箭头函数时,this指向定义箭头函数时所在上下文的this值。
const foo = () => {
console.log(this); // 输出 window 对象,捕获外部的 this
};
foo();
const obj = {
name: 'Alice',
greet() {
const inner = () => {
console.log(this.name); // 捕获外部 greet 方法的 this
};
inner();
}
};
obj.greet(); // 'Alice'
事件处理函数中的this
在DOM事件处理函数中,this默认指向触发事件的DOM元素。
const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this); // 输出触发事件的按钮元素
});
this的显式绑定
call,apply,bind可以显式的绑定this指向特定对象。
function greet() {
console.log(this.name);
}
const obj = { name: 'Alice' };
greet.call(obj); // 'Alice'
greet.apply(obj); // 'Alice'
const boundGreet = greet.bind(obj);
boundGreet(); // 'Alice'
总结
this 是动态绑定的,取决于函数调用的上下文。
普通函数调用时,this 指向全局对象(非严格模式)或 undefined(严格模式)。
对象方法调用时,this 指向该对象。
构造函数调用时,this 指向新创建的实例。
箭头函数没有自己的 this,它会继承外部函数的 this。
显式绑定:通过 call()、apply() 或 bind() 可以显式设置 this。
理解 this 的关键在于上下文:是如何调用函数的、调用时的环境如何,它决定了 this 的指向。