在javascript里面,apply和call都是为了改变函数运行时的上下文(context)产生的,说白了,就是改变函数中this的指向。
javascript有个特点【定义上下文】和【运行上下文】以及【上下文是可以改变的】这个概念。
call和apply二者,作用基本完全一样,只是接受参数的方式不一样。
func.call(this, arg1, arg2); func.apply(this, [arg1, arg2])
其中this是你想指定的上下文,他可以是任何一个javascript对象(javascript中一切皆对象),call需要按照顺序传递参数进去,
apply是把参数放在一个数组里面。
javascript中某些函数参数数量是不确定的,所以只能在参数明确知道时才能用call,否则用apply,然后把参数push进数组传进去,当参数不确定时
函数内部也可以使用arguments这个数组遍历所有参数。
具体来说:
1,数组之间的追加
1 var array1 = [12 , "foo" , {name "Joe"} , -2458]; 2 var array2 = ["Doe" , 555 , 100]; 3 Array.prototype.push.apply(array1, array2); 4 /* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
2,获取数组中的最大值和最小值
1 var numbers = [5, 458 , 120 , -215 ]; 2 var maxInNumbers = Math.max.apply(Math, numbers), //458 3 maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
number本身没有max方法,但是math有,我们就可以借助 call 或者 apply 使用其方法。
3、验证是否是数组(前提是toString()方法没有被重写过)
1 functionisArray(obj){ 2 returnObject.prototype.toString.call(obj) === ‘[object Array]‘ ; 3 }
4、类(伪)数组使用数组方法
1 var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。
bind也可以改变函数内部this指向,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。