返回

this 指向、call、apply 和 bind 的妙趣横生区别

前端

this 指向

普通函数调用

function sayHello() {
  console.log(this);
}

sayHello(); // window

在普通函数调用中,this 指向 window 对象。这是因为 JavaScript 中的函数都是全局作用域的,因此在普通函数调用时,this 默认指向 window 对象。

构造函数调用

function Person(name) {
  this.name = name;
}

const person = new Person('张三');

console.log(person.name); // 张三

在构造函数调用中,this 指向实例对象。这是因为在构造函数中,this 会被自动绑定到新创建的实例对象上。因此,在构造函数内部,this 可以访问和修改实例对象中的属性和方法。

对象方法调用

const person = {
  name: '张三',
  sayHello: function() {
    console.log(this.name);
  }
};

person.sayHello(); // 张三

在对象方法调用中,this 指向该方法所属的对象。这是因为在对象方法内部,this 会被自动绑定到该方法所属的对象上。因此,在对象方法内部,this 可以访问和修改该对象中的属性和方法。

通过事件绑定的方法

const button = document.getElementById('btn');

button.addEventListener('click', function() {
  console.log(this);
});

button.click(); // <button id="btn">按钮</button>

通过事件绑定的方法,this 指向的是绑定事件的元素。这是因为在事件处理函数内部,this 会被自动绑定到触发该事件的元素上。因此,在事件处理函数内部,this 可以访问和修改该元素的属性和方法。

call、apply 和 bind

call、apply 和 bind 都是用来改变 this 指向的方法。它们可以让我们更加灵活地使用函数。

call

function sayHello(name) {
  console.log(this.name + ' 对 ' + name + ' 说你好');
}

const person1 = {
  name: '张三'
};

const person2 = {
  name: '李四'
};

sayHello.call(person1, '王五'); // 张三 对 王五 说你好
sayHello.call(person2, '赵六'); // 李四 对 赵六 说你好

call 方法可以显式地指定 this 指向的对象。在上面的例子中,我们使用 call 方法将 this 指向 person1 和 person2 对象,从而改变了 sayHello 函数内部的 this 指向。

apply

function sayHello(name) {
  console.log(this.name + ' 对 ' + name + ' 说你好');
}

const person1 = {
  name: '张三'
};

const person2 = {
  name: '李四'
};

sayHello.apply(person1, ['王五']); // 张三 对 王五 说你好
sayHello.apply(person2, ['赵六']); // 李四 对 赵六 说你好

apply 方法与 call 方法类似,都可以显式地指定 this 指向的对象。但是,apply 方法的参数是一个数组,而 call 方法的参数是一个一个传递的。

bind

function sayHello(name) {
  console.log(this.name + ' 对 ' + name + ' 说你好');
}

const person1 = {
  name: '张三'
};

const person2 = {
  name: '李四'
};

const sayHelloToWangWu = sayHello.bind(person1, '王五');
const sayHelloToZhaoLiu = sayHello.bind(person2, '赵六');

sayHelloToWangWu(); // 张三 对 王五 说你好
sayHelloToZhaoLiu(); // 李四 对 赵六 说你好

bind 方法可以创建一个新的函数,该函数的 this 指向被固定为指定的 this 值。在上面的例子中,我们使用 bind 方法创建了两个新的函数 sayHelloToWangWu 和 sayHelloToZhaoLiu,它们的 this 指向分别被固定为 person1 和 person2 对象。因此,当我们调用 sayHelloToWangWu 和 sayHelloToZhaoLiu 时,它们的 this 指向不会发生变化,仍然指向 person1 和 person2 对象。

总结

this 指向、call、apply 和 bind 是 JavaScript 中非常重要的概念,它们可以帮助我们更加灵活地使用函数。

  • this 指向决定了函数内部的 this 指向哪个对象。
  • call、apply 和 bind 都可以改变 this 指向。
  • call 方法可以显式地指定 this 指向的对象,参数是一个一个传递的。
  • apply 方法可以显式地指定 this 指向的对象,参数是一个数组。
  • bind 方法可以创建一个新的函数,该函数的 this 指向被固定为指定的 this 值。

希望本文对您理解 this 指向、call、apply 和 bind 有所帮助。