this指针详解(js版)

122 阅读2分钟

前言

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 的指向。