每个函数都包含两个非继承而来的方法:call和apply.
我们可以通过这两个方法来间接调用函数。可以这样:
f.call(o);
f.apply(o);
//o对象间接调用了f函数
这与下面的功能相似:
o.m = f;
o.m();
delete o.m//删除临时方法
语法:
fn.call(obj,arg1,arg2,arg3...) fn.apply(obj,[arry]/arguments) [apply中第二个参数可以使纯数组也可以是类数组]
在es5严格模式下,第一个参数都会变成this值;而在es3和非严格模式下,undefined和null被全局对象所代替,其他原始值则会被相应的包装的对象所替代。
“call和apply最强大的地方是能够扩充函数赖以运行的作用域”,很多博客文章中都是这样描述的,其实这种说法是错误的,绝对是错误的!所以我不用“误区”这个词语了。因为JS是静态词法作用域,是按照语法定义来确定作用域,它的作用域其实是无法扩充的,而this 是 context,可以改变 ,call和apply改变的是this,改变的是上下文!
下面是一个例子:
var name = "复读机",
age = ;
function say(){
console.log("name : " + this.name);
console.log("age : " + this.age);
}
var obj = {
name : "bb机",
age :
}
say(); //name : 复读机 age : 25
say.call(obj);//name : bb机 age : 30
如果我们不使用call方法,我们是怎么用obj调用say这个函数的呢
var name = "复读机",
age = ;
function say(){
console.log("name : " + this.name);
console.log("age : " + this.age);
}
var obj = {
name : "bb机",
age :
}
say(); //name : 复读机 age : 25
obj.say = say;
obj.say();//name : bb机 age : 30
可以看出用call将会更方便!
或许我们使用过require框架中的require函数,觉得非常神奇!它可以将一个数组依次传入一个回调函数的参数中,其实它的模型非常简单!
下面是例子:
var noop = function(){};
function require(list,fn){
fn.apply(noop,list);
}
require([,,],function(a,b,c){
console.log(a);
console.log(b);
console.log(c);
})
今天到此为止哈。。