面试题答案
一键面试箭头函数中 call、apply、bind 方法的特殊情况
- 箭头函数没有自己的 this:箭头函数本身不绑定 this,它的 this 继承自外层作用域。所以在箭头函数中使用 call、apply、bind 方法试图改变 this 指向是无效的。
- call 和 apply 行为:当在箭头函数上调用 call 或 apply 时,传入的第一个参数(通常用于指定 this 指向)会被忽略,箭头函数始终使用外层作用域的 this。
- bind 行为:在箭头函数上调用 bind 方法,同样不会改变箭头函数内部的 this 指向,它返回的新函数仍然使用外层作用域的 this。不过 bind 返回的函数会记住调用 bind 时传入的参数,并在调用新函数时将这些参数前置传入。
复杂业务逻辑中合理运用
- 普通函数结合箭头函数:在需要改变 this 指向的地方使用普通函数,在需要简洁语法且依赖外层 this 的地方使用箭头函数。
- 使用闭包保持 this 一致性:利用闭包来传递正确的 this 指向,确保在复杂逻辑中 this 的稳定。
代码示例及原理说明
// 普通函数
function normalFunction() {
console.log(this);
}
const obj = { name: 'John' };
normalFunction.call(obj); // { name: 'John' },call 改变了 this 指向到 obj
// 箭头函数
const arrowFunction = () => {
console.log(this);
};
arrowFunction.call(obj);
// 这里输出的是外层作用域的 this(在浏览器环境中通常是 window 对象),
// 因为箭头函数没有自己的 this,不会被 call 改变指向
// 复杂业务逻辑示例
const parentObject = {
name: 'Parent',
execute: function() {
// 这里的 this 指向 parentObject
const innerArrowFunction = () => {
console.log(this.name); // 输出 'Parent',因为继承了外层的 this
};
innerArrowFunction();
// 使用普通函数结合箭头函数
function normalInnerFunction() {
const anotherArrowFunction = () => {
console.log(this.name); // 输出 'Inner',通过 call 改变了外层普通函数的 this,进而影响箭头函数
};
anotherArrowFunction.call({ name: 'Inner' });
}
normalInnerFunction();
}
};
parentObject.execute();
在上述代码中,arrowFunction
中调用 call
并没有改变 this
指向,因为箭头函数依赖外层作用域的 this
。在 parentObject.execute
方法中,内部箭头函数 innerArrowFunction
继承了外层 execute
方法的 this
。而在 normalInnerFunction
中,通过 call
改变了外层普通函数的 this
,使得内部箭头函数 anotherArrowFunction
也受到影响,体现了普通函数和箭头函数在处理 this
指向时的协同关系。