apply与call方法,用起来(js)
首先在我谈及apply和call方法怎么用时,必须要说一下function(函数)。
函数是JavaScript中的特殊对象,既然是对象那它就一定可以有属性和方法,而它有几个内置的属性和方法
属性:length、name、arguments、caller、prototype;
var function a(){}
console.log(Object.getOwnPropertyNames(a)) 用该法可查其不可配置的自有属性
//["length", "name", "arguments", "caller", "prototype"]方法:call、apply、bind、toString。 可以new 一个函数查看其原型就可以看见
对这些属性我就略过;着重讲我们今天的主题,有很多人都知道这两个方法但是大都不怎么用,但是这两个方法真的很有用,尤其在借助原生方法实现我们自己的方法时,我们众所周知的jQuery插件中大量运用这两个方法来实现自己包装过的方法。如$.each(),$.extend(),$.inArray(),$.type()等,感觉是不是很强大。
1、先看定义(来源JavaScript权威指南6)
call()方法和apply()的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用。
在ECMAScript5的严格模式中,call()和apply()的第一个参数都会变为this的值,那怕传入的实参是原始值甚至是null或undefined。在ECMAScript3和非严格模式中,传入的null和undefined都会被全局对象代替,而其他原始值则会被相应的包装对象所替代。
call(),第一个调用上下文实参之后的所有实参就是要传入待调用函数的值;
apply()就两个参数,第二个是一个数组或类数组对象
var bigcall = Math.max.call('',1,2,5);
var bigapply = Math.max.apply('',[1,2,5])
在此我举例说明怎么用,以$.type(),$.each()来举例子
首先针对这两个方法来简单的模拟jQuery
var toString = Object.prototype.toString,class2type={};
var jQuery=function(){
//真实的jQuery不是这样的,我们只是为了例子简单写
}
jQuery.type=function(obj){
return obj ==null? String(obj):
class2type[ toString.call(obj) ] || "object"};
jQuery.each=function (object,callback){
//这里只简单写一下
var name,i=0,
length=object.lenth,
isObj = length===undefined || jQuery.type(object)==='function';
if(isObj){
for(name in object){
if(callback.call(object[name],name,object[name])===false)
break;
}
}else {
for(;i<length;){
if(callback.call(object[i],i,object[i++])===false)
break;
}
}
return object}
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(i,name) {
class2type["[object "+name+"]"] =name.toLowerCase();
});//这里我们用了toString方法,如果你直接给该方法中传参不管是什么该方法都返回Object.prototype.toString([]) "[object Object]"。但是用了call方法就会显示的将该方法的this指向传入的第一个参数,所以会返回"[object Array]"。call和apply方法都有显示的改变this的功能
这个方法又可以这么改写;var obj = []; 这个obj可以是任意类型,什么类型this指向谁。
obj.m = Object.prototype.toString;
obj.m() //"[object Array]"
其实只要是方法不管内置的,自己定义的我们都可以调用call或apply(是个方法都能用,他是方法的方法,在此不纠结定义)。只要符合其传参要求即可,它们只是改变了this的指向。(干的是挂羊头卖狗的事情)
大家打开jQuery的源码看一遍就发现好多call和apply方法