本文详细解析JavaScript中直接调用函数与使用call、apply方法的区别。重点阐述call和apply如何动态修改this指向以实现对象冒充,并对比两者在参数传递形式上的差异:call需逐个列出参数,apply需以数组形式传入。
本文通过实例分析,阐述JavaScript中直接调用函数与使用call方法调用的具体区别,供读者参考。
直接调用方式
直接调用函数是最常见且基础的方式。其核心逻辑是以函数所属的对象作为调用者,在函数名后的括号内传入相应参数来执行函数。
例如:
window.alert("测试代码");
需要注意的是,如果调用者是全局对象window,则可以省略不写,例如直接执行alert("测试代码");。
使用call()方法调用函数
其语法结构为:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);
初学者可能认为直接调用已足够,但实际上直接调用虽然简单,却缺乏灵活性。当需要在运行时动态传入函数引用以执行特定逻辑时,必须使用call方法来动态调用函数。
具体示例如下:
<script type="text/javascript">
var each =function(array,fn)
{
for(var index in array)
{
fn.call(null,index,array[index]);
}
}
each([4,20,3],function (index,ele)
{
document.write("第"+index+"个元素是"+ele+"<br/>");
}
);
</script>
该示例初看可能较为复杂,关键在于fn.call语句。call方法的调用格式要求将调用者(对象)作为第一个参数填入,后续按顺序输入其余参数。这种形式与直接调用不同,调用者不是写在函数名前面,而是作为call方法的第一个参数。格式为:fn.call(obj,args);
读者可能会问,call调用与直接调用的核心区别是什么?区别在于call调用改变了this指针的指向。如果被调用的函数内部没有使用this,那么两种调用方式在结果上就没有区别。
再举一个被调用函数中包含this指针的例子:
var x = "我是全局变量"; //定义全局变量x
function a(){ //定义函数类结构a
this.x = "我是在函数类结构a中声明的哦";
}
//定义普通函数,弹出当前指针所包含的变量x的值
function f(){
alert (this.x);
}
//返回值为“我是在函数类结构a中声明的哦”
f.call(new a());
我的理解是,f.call(new a())的作用是将函数(在JavaScript中函数也是对象)f“复制”到被调用对象“new a()”的作用域下进行解析。事实上,这段代码的执行结果与下面这段代码一致:
function a(){
this.x = "我是在函数类结构a中声明的哦";
alert(this.x);
}
a();
实质上,在调用f.call()时,修改了f()函数内部的this指向。原本f中的this.a和this.b属性属于f自身,但通过f.call()调用并传入新对象e()(作为新的this)时,e被绑定到了f的this中。原本属于f的属性,现在被添加到了e中。(注:e与e()、f与f()在此语境下等价)。这类似于“继承”,但在JavaScript中更准确的说法是“对象冒充”。
使用apply()方式调用函数
apply()方法与call()方法功能基本相似,均可用于动态调用函数。两者的主要区别如下:
- 通过call()调用函数时,必须在括号中详细地列出每个参数。
- 使用apply()动态调用函数时,需要将所有调用参数以数组的形式一次性传入。
其语法结构为:apply([thisObj [,argArray]]);
例如,下面两条语句的执行效果是相等的:
myfun.call(window,12,13);
myfun.capply(window,[12,13]);
在修改this指针指向这一特性上,apply()与call()保持一致。
总体而言,apply()与call()仅在参数传递的形式上存在差异。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码的运行效果。
更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家理解JavaScript程序设计有所帮助。