也谈js中的call 和 apply

作者: 行者N | 来源:发表于2017-02-07 18:46 被阅读122次

在看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 下的所有方法了

相关文章

网友评论

    本文标题:也谈js中的call 和 apply

    本文链接:https://www.haomeiwen.com/subject/fcsmittx.html