04/20
2017
JavaScript中每个函数都有call()和apply()方法(呼叫和申请 XD),这两个方法都是为了改变函数的this值。简单地说,如果一个对象没有某个方法,但是其他人有,那么就可以用call()或apply()来借用这个方法。
call()和apply()方法的参数都分为两个部分,第一个参数是要作为this的对象,其他参数是要借用的函数的参数。
如果第一个参数为null或缺省,就会把this指向全局对象(window)。
如下代码:
var a={ name:"saber", say:function () { console.log(this.name); } }, b={ name:"我是2b" }; a.say.call(b);
a有个say()方法,可以说出自己的名字,但b没有这个方法。我们用a的say方法来call(呼叫)b,说我也不是谦虚,还是你来吧。这样a的this就变成了b,this.name也就是b的name了。
操作NodeList时常常借助数组的方法,代码如下:
var img=document.querySelectorAll("img"); [].slice.call(img,0,5); [].forEach.call(img,function (no) { console.log(no.src); }); //[]相当于Array.prototype的简写
上面用的都是call,那么apply和call有什么区别呢?其实功能是一样的,只是apply第一个参数之外的参数需要是数组形式,如果不是数组的话就手动创建成数组,如:
var img=document.querySelectorAll("img"); [].forEach.apply(img,[function (no) { console.log(no.src); }]);
当参数数量不固定,或者参数是数组或类似数组时(如函数的参数集合arguments),用apply就比较方便。
还有个比较有用的,在数组里取出最大值最小值:
var a=[0,1,3,5,7,9,10]; console.log(Math.max.apply(null, a)); //取出最大值 console.log(Math.min.apply(null, a)); //取出最小值
此外,通过call和apply,我们可以实现对象继承,如下:
var Parent = function(){ this.name = "yjc"; this.age = 22; } var child = {}; Parent.call(child);
这样,child就继承了Parent的所有属性。其实运行过程就相当于Parent是一个构造函数,child进去走一圈之后,被设置上了属性。
面试经典问题~~ _(:3」∠)_
感觉你在偷偷准备什么~~~