javascript中call和apply的模拟实现

call()

call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。

语法:fun.call(thisArg, arg1, arg2, ...)

实例:

var name="lee";
var obj={
    name:"lwf"
};
function foo(){
    console.log(this.name);
}
foo();//lee(浏览器环境)
foo.call();//lee,无参数,this默认指向window
foo.call(null);//,lee,指向window
foo.call(undefined);//lee,指向window
foo.call(obj);//lwf。有参数,this指向obj
var obj={
    name:"lwf"
};
function foo(age){
    console.log(age);
}
foo.call(obj,21);//21
var obj={
    name:"lwf"
};
function foo(age){
    return age;
}
console.log(foo.call(obj,21));//21

由此可以看到call方法的作用:

  1. 如果没有参数,或者只有一个参数,参数为null,undefined时,this指向window
  2. 如果有多个参数,并且参数不确定,第一个参数作为this绑定的对象,其余参数作为参数传入foo方法
  3. 如果foo方法有返回值,那么使用call调用后,也应该是有返回值的

    据此,我们实现了如下函数:

Function.prototype.call2=function(context){
    var context=context||window;//考虑有参数和没有参数的情况的this指向
    context.fn=this;//把调用call的方法作为指定的上下文对象的一个属性
    var args=[].slice.call(arguments,1);//取得除了上下文对象以外的参数
    var result=eval('context.fn('+args+')');//考虑有无return,执行该方法
    delete context.fn;//删除该方法
    return result;
};

类似的,apply的模拟实现:

Function.prototype.apply2=function(context){
    var context=context||window;
    context.fn=this;
    var args=arguments[1];
    var result;
    if(args){
        result=eval('context.fn('+args+')');
    }else{
        result=context.fn();
    }
    delete context.fn;
    return result;
};

参考:JavaScript深入之call和apply的模拟实现 #11

猜你喜欢

转载自blog.csdn.net/liwenfei123/article/details/80582085
今日推荐