JS 改变 this 指向的方法
在 JavaScript 中,有三种主要方法可以改变函数中 this
的指向,分别是 call()
、apply()
和 bind()
。这三种方法,初学者经常搞不清楚,面试过程中容易忽略
本文来探讨一下他们的区别
call () 方法
立即执行函数
第一个参数是新的 this 指向
后续参数以逗号分隔传递给函数
```javascript function greet(message) { console.log(${message}, ${this.name}
); }
const person = { name: "Alice" };
// 使用 call 改变 this 指向 greet.call(person, "Hello"); // 输出: Hello, Alice
```
apply () 方法 1. 立即执行函数
第一个参数是新的 this 指向
第二个参数是数组,数组中的元素作为参数传递给函数 ``` javascript function calculateSum(a, b) { return a + b + this.base; }
const context = { base: 10 };
// 使用 apply 改变 this 指向 const result = calculateSum.apply(context, [5, 3]); console.log(result); // 输出: 18 (5+3+10)
```
bind () 方法
不会立即执行函数,而是返回一个新的函数
新函数中的 this 被永久绑定到指定的对象
可以预先传递部分参数(柯里化)
``` javascript function introduce(age) { console.log(I'm ${this.name}, ${age} years old
); }
const person = { name: "Bob" };
// 使用 bind 改变 this 指向,返回新函数 const boundIntroduce = introduce.bind(person); boundIntroduce(25); // 输出: I'm Bob, 25 years old
// 预先传递参数 const boundWithAge = introduce.bind(person, 30); boundWithAge(); // 输出: I'm Bob, 30 years old
```
总结区别
++call++() 和 apply() 会立即执行函数,而 bind() 返回一个新函数
call() 接收逗号分隔的参数,apply() 接收数组形式的参数
bind() 绑定后,无论如何调用,this 指向都不会改变
在 ES6 中,箭头函数没有自己的 this,它会继承外层作用域的 this,因此以上方法无法改变箭头函数的 this 指向。
this 指向问题
来看一个经典问题
var x = 1;
var obj = {
x: 2,
fun: function () {
var x = 5;
console.log(this.x);
},
fun1: () => {
var x = 6
console.log(this.x);
}
}
var fun = obj.fun;
obj.fun();
fun();
obj.fun1();
这段代码,在浏览器端的输出是
2 1 1
在 node 环境的输出是
2
undefined
undefined
分析如下:
函数 this 指向调用它本身的对象
obj.fun()
表达式中,函数fun
的调用方是 obj。那么this
为obj
对象,返回 1fun()
没有任何的调用方,this 指向外层的 global 对象。对于浏览器环境,global 是window 对象,使用 var 声明的变量,都会挂载在 window 对象上。所以 window.x = 1。而 node 环境不会自动挂载,所以这里是 undefined。obj.fun1()
是个箭头函数,它会继承外层作用域的 this,和 3 的获取值一样。
原文地址:https://webfem.com/post/js-this,转载请注明出处