当诸如prototype.js、mootools.js、jQuery.js这些框架出现后,在其代码中能看见大量call和apply方法的调用。这里拿mootool中的为例,如:
Array.extend({forEach:function (C, D) { for (var B = 0, A = this.length; B < A; B++) { C.call(D, this[B], B, this); } }
这段代码的作用是为Array原型扩展forEach这样一个迭代方法。参数C是一个函数,参数D则是我们传入的一个对象。一般性使用例子是:
[1,2,3,4].forEach(function(item){ alert(item); })
结果是:连续的弹出1,2,3,4. 我们在看下面的代码:
var object = "传入的对象"; [1,2,3,4].forEach(function(item){ alert(item); alert(this); },object)
结果是:1,传入的对象,2,传入的对象,3,传入的对象,4,传入的对象, 可以看见传入的object替代了forEach方法中匿名函数中的上下文,所以alert出来的this是"传入的对象"。
[1,2,3,4].forEach(function(item,index,array){ alert(item); alert(this); alert(index); alert(array); })
如上代码,item数组中单个数,此数的index值,数组本身。如用apply来代替call代码将如下:
Array.extend({forEach:function (C, D) { for (var B = 0, A = this.length; B < A; B++) { C.apply(D, [this[B], B, this]); } }
不同的写法是因为apply和call参数传入的不用: apply第一个参数是要“代替”这个function对象实例中的上下文this,第二个参数是传递给这个funciton对象的所有参数组合而成的数组。call第一个参数作用和apply相同,而第二个参数以后的参数[0个或N个]将传递给这个funciton对象的参数。