JavaScript中call与apply的核心差异与继承应用
在JavaScript中,call 和 apply 是改变函数执行上下文(即 this 指向)的核心工具,二者功能相似但参数传递方式不同。本文将详解其语法结构、this 指向逻辑以及在对象继承中的应用,帮助开发者理清概念,避免参数格式错误。
核心定义与语法结构
call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。它与 apply() 作用类似,唯一区别在于参数接收形式:call 接受逐个列出的参数,而 apply 接受一个包含多个参数的数组。
语法如下:
fun.call(thisArg[, arg1[, arg2[, ...]]])
fun.apply(thisArg, [argsArray])
this 指向机制与非严格模式行为
thisArg 是在函数运行时指定的上下文对象。理解这一概念的关键在于:this 的值由函数的调用方式决定,而非定义位置。
- 显式绑定:当使用
call或apply时,this将指向传入的第一个参数。 - 非严格模式陷阱:若指定为
null或undefined,this会自动指向全局对象(浏览器中为window)。此外,原始值(数字、字符串、布尔值)会被自动包装为对应的对象实例。
第1步:验证 this 指向变化
目的是观察当 thisArg 改变时,函数内部属性访问的变化。入口为控制台代码片段,动作是定义对象与函数并执行调用,参数为不同的对象引用。
var p = "456";
function f1() {
this.p = "123";
}
function f2() {
console.log(this.p);
}
f2(); // 输出: 456 (全局变量)
f2.call(f1()); // 输出: 123 (f1的对象属性)
f2.apply(f1()); // 输出: 123 (f1的对象属性)
第一次调用直接输出全局变量 p。后续因使用了 call 和 apply,f2 中的 this 被重定向至 f1 的实例,从而读取到其自身定义的属性。这种“借用”方法是实现面向对象中继承的一种手段。
注意:若移除 f1 中的 this.p,输出将恢复为三个 456,这证实了当绑定对象无该属性且未定义时,回退机制会寻找全局变量。
第2步:利用 call 实现属性继承
既然能借用方法,同样可以借用构造函数中的属性赋值,从而实现浅层继承。动作是将 call 置于子构造函数内。
function f1() {
this.father = "father";
}
function f2() {
f1.call(this); // 将 f1 的执行上下文绑定到当前 f2 实例
this.child = "child";
}
var test = new f2();
console.log(test.father); // 输出: father
在 f2 内部执行 f1.call(this) 时,this 指向正在创建的 f2 实例。因此,f1 对 this 的属性赋值操作,实际上是为 f2 的新实例添加了属性。这是基于构造函数模式的经典继承写法。
参数传递的关键区别
call 和 apply 的主要差异体现在剩余参数上。call 逐个接收参数,apply 必须接收一个数组作为第二参数。
第3步:测试参数传递差异
目的是对比正确与错误的参数格式,观察控制台输出或报错信息。入口为定义带参数的函数,动作是分别以不同格式传入参数。
function f1(){ this.p = "测试call"; }
function f2(x, y, z) {
console.log(this.p);
console.log(x);
console.log(y);
console.log(z);
}
function f3(){ this.p = "测试apply"; }
// 测试1: call 逐个传参 (成功)
f2.call(f1(), 4, 5, 6);
// 测试2: call 传入数组 (失败)
f2.call(f1(), [4, 5, 6]);
// 测试3: apply 传入数组 (成功)
f2.apply(f3(), [4, 5, 6]);
// 测试4: apply 逐个传参 (失败)
f2.apply(f3(), 4, 5, 6);
根据执行结果分析:
- 第一段:
call正常接收4, 5, 6作为独立参数,输出符合预期。 - 第二段:
call将[4, 5, 6]视为第一个参数x,导致y和z为undefined。 - 第三段:
apply正确解析数组内的元素,分别赋给x, y, z。 - 第四段:
apply严格要求第二个参数为数组或类数组对象,直接传入逗号分隔的值会抛出语法错误。
简要总结
call 和 apply 是 JavaScript 高级特性的基石,主要用于控制 this 指向和实现函数复用。记住口诀:Call 后面跟着参数序列,Apply 后面跟着一个数组。在实际开发中,常结合 Function.prototype.bind 或箭头函数来处理复杂的事件回调,但掌握底层原理有助于调试深层 bug。以上就是 JavaScript 中 call 与 apply 的详细解析,更多关于前端基础进阶的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









