前端面试题之JS手写apply

前端面试题之JS手写apply

参考之前手写的call方法:
https://blog.csdn.net/qq593249106/article/details/83115935

Function.prototype.call2 = function (obj) {
    var obj = obj || window;
    var args = [];
    for(var i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i + ']');
    }
    obj.fn = this;
    var result = eval('obj.fn('+args+')');
    delete obj.fn;
    return result;
};

观察call和apply:

func.call(thisArg, arg1, arg2, arg3…)
func.apply(thisArg, [argsArray])

call和apply的区别就是,apply参数是以数组的形式传的,可以看看下面这个例子

var value = 'v in window';
function func() {
    arguments = [].splice.call(arguments, 0); //这一句是把参数转成数组,因为arguments不是数组,输出的时候容易观察
    console.log(arguments);
    console.log(this.value);
}
var obj = {
    value: 'v in obj'
};
func.call(obj, 1,2,3);
//[1, 2, 3]
//v in obj
func.apply(obj, [1,2,3]);
//[1, 2, 3]
//v in obj

之前手写call的操作是把参数整合成数组args:

var args = [];
for(var i = 1; i < arguments.length; i++) {
    args.push('arguments[' + i + ']');
}

然而apply是直接传进来一个参数,省去了整合过程,直接把arguments[1]放进去:

var result = eval('obj.fn('+arguments[1]+')'); //arguments[1]是func.apply2(obj, [1,2,3])的[1,2,3]

再处理一下不传参的情况:

if(!arguments[1]) {
    result = obj.fn;
}else {
    result = eval('obj.fn('+arguments[1]+')');
}

最终代码:

var value = 'v in window';
function func() {
    arguments = [].splice.call(arguments, 0); //这一句是把参数转成数组,因为arguments不是数组,输出的时候容易观察
    console.log(arguments);
    console.log(this.value);
}
var obj = {
    value: 'v in obj'
};
Function.prototype.apply2 = function (obj) {
    var obj = obj || window;
    obj.fn = this;
    var result;
    if(!arguments[1]) {
        result = obj.fn;
    }else {
        result = eval('obj.fn('+arguments[1]+')');
    }
    delete obj.fn;
    return result;
};
func.apply(obj);
//[]
//v in obj
func.apply(obj, [1,2,3]);
//[1,2,3]
//v in obj
func.apply2(obj);
//[]
//v in obj
func.apply2(obj, [1,2,3]);
//[1,2,3]
//v in obj

猜你喜欢

转载自blog.csdn.net/qq593249106/article/details/83117370
今日推荐