在看js中的模块机制的时候,对于其中出现的apply比较模糊,网上查了许多,这里主要还是自己的理解和记录,有抄袭的成分。
在 javascript 中,call 和 apply 是Function对象自带的方法,都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向
这么说模糊吗?有些掉书袋了,还是用例子来说明吧。下面是网上的一个常用的例子
function fruits() {}
fruits.prototype = {
color: "red",
say: function() {
console.log("My color is " + this.color);
}
}
var apple = new fruits;
apple.say(); //My color is red
banana = {
color: "yellow"
}
apple.say.call(banana); //My color is yellow
apple.say.apply(banana); //My color is yellow
例子可以说明,banana使用了apple的say的方法,但是在使用say时,调用的还是自己作用域中的变量。
apply、call 的区别
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样
举例说明
var func = function(arg1, arg2) {
};
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
其中 this 就是类似banana(需要使用func的对象),arg1,arg2 是func需要的参数。
JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。
而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。
apply、call 的常见用法
- 数组追加
var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
- 获取数组中的最大值和最小值
var numbers = [5, 458 , 120 , -215 ];
var maxInNumbers = Math.max.apply(Math, numbers), //458
maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法
- 验证是否是数组(前提是toString()方法没有被重写过)
functionisArray(obj){
returnObject.prototype.toString.call(obj) === '[object Array]' ;
}
- 类(伪)数组使用数组方法
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了