this 指向、call、apply 和 bind 的妙趣横生区别
2024-02-16 11:29:29
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 有所帮助。