深入理解JavaScript中call()方法的对象冒充与继承机制

作者:函数茶馆时间:2026-10-26 13:47:11浏览:569

本文基于jQuery源码中的toArray()方法,深入解析JavaScript中call()函数的核心机制。通过对比MDN文档与StackOverflow案例,详细阐述call如何改变函数执行时的this指向,实现对象间的方法借用与对象冒充。文章结合具体代码示例,厘清call与apply的区别,并探讨其在模拟面向对象继承中的应用。

起因:


jQuery源码中的call应用

在研读snandy关于jQuery DOM元素获取的系列文章时,注意到toArray()方法的实现细节。相关jQuery源码如下:


代码如下:

 
toArray: function() {
return slice.call( this, 0 );
}, 
get: function( num ) {
return num == null ?
// Return a 'clean' array
this.toArray() :
// Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] );
}, 

源码中slice.call(this, 0)的用法引发了思考。虽然此前查阅手册知晓call用于对象冒充和继承,但jQuery源码结构较为复杂,因此将这部分逻辑剥离出来,单独构建测试文件以观察其具体执行流程。



call方法机制解析

尽管有所预习,仍决定深入探究call机制。参考MDN官方文档,并辅以牛津大辞典辅助理解英文释义,旨在提升英语阅读能力的同时,为其他开发者提供清晰的参考(翻译如有疏漏,恳请指正)。


call


摘要:


该方法允许使用指定的this值和独立参数列表来调用一个函数。


注意:call与apply语法相似,主要区别在于参数传递方式:call接受参数列表,而apply接受参数数组。


Function类的一个方法:版本JavaScript 1.3版以后


语法:


fun.call(thisArg[, arg1[, arg2[, ...]]])


参数说明:


thisArg:


指定fun()调用时的上下文对象。需注意:在非严格模式下,若传入null或undefined,this将被替换为全局对象,原始值会被包装。


arg1,arg2,....


传递给函数的参数列表。


描述:


当调用已存在的函数时,可以分配不同的对象作为执行上下文。此时,this指向当前被指定的对象。


利用call,可以复用单一方法定义,供其他对象继承使用,无需在创建新对象时重新编写该方法(即对象冒充,下文有示例说明)。



对象冒充与代码示例

MDN官网提供了相关示例。此外,在StackOverflow的一个相关问题回答中,对对象冒充机制的解释令人豁然开朗。


摘录该部分核心内容(点击查看原文):



In javascript, methods of an object can be bound to another object at runtime. In short, javascript allows an object to "borrow" the method of another object:


代码如下:

 
object1 = {
name:'frank',
greet:function(){
alert('hello '+this.name)
} 
}; 
object2 = {
name:'andy'
}; 
// Note that object2 has no greet method.
// But we may "borrow" from object1:
object1.greet.call(object2);

The call and apply methods of function objects (in javascript functions are objects as well) allows you to do this. So in your code you could say that the Nodelist is borrowing an array's slice method. What does the conversion is the fact that slice returns another array as it's result.



首句形象地指出:在JavaScript中,对象方法可在运行时绑定至另一对象。简言之,JS允许对象“借用”非自身拥有的方法。所谓“冒充”,如例所示,即object2通过call借用object1的方法进行调用。



PS:作为新手首次撰写博客,内容可能略显杂乱,期望未来能逐步改进。向各位前辈学习博客写作技巧,欢迎批评指正!


参考资料: 1.w3cschool ECMAScript 继承机制实现

2.MDN上call的说明

3.stackoverflow

作者最新文章