JavaScript 深入之 call 和 apply 的模拟实现

发布时间:2019-08-10 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了JavaScript 深入之 call 和 apply 的模拟实现脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
// 第一版
Function.PRototyPE.call2 = function(context) {
    // 首先要获取调用call的函数,用this可以获取
    // this的指向为bar,因为bar是FuncITon的实例
    context.fn = this;
    context.fn();
    // 相当于把bar挂载到foo上,所以bar可以取到value
    delete context.fn;
}

// 测试一下
VAR foo = {
    value: 1
};

function bar() {
    console.LOG(this.value);
}

bar.call2(foo); // 1

但是第一版不可以传递多个参数

// 第二版
Function.prototype.call2 = function(context) {
    context.fn = this;
    var args = [];
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }
    eval('context.fn(' + args +')');
    //这里 args 会自动调用 Array.toString() 这个方法。
    //这里eval函数输出的是:context.fn(arguments[1],arguments[2])
    delete context.fn;
}

// 测试一下
var foo = {
    value: 1
};

function bar(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value);
}

bar.call2(foo, 'kevin', 18);
// kevin
// 18
// 1

第二版的问题是,1.this 参数可以传 null,当为 null 的时候,视为指向 window2.函数是可以有返回值的!

// 第三版
Function.prototype.call2 = function (context) {
    var context = context || window;
    context.fn = this;

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

    var result = eval('context.fn(' + args +')');
    delete context.fn
    return result;
}

// 测试一下
var value = 2;

var obj = {
    value: 1
}

function bar(name, age) {
    console.log(this.value);
    return {
        value: this.value,
        name: name,
        age: age
    }
}

bar.call2(null); // 2

console.log(bar.call2(obj, 'kevin', 18));
// 1
// Object {
//    value: 1,
//    name: 'kevin',
//    age: 18
// }

es6

Function.prototype.call2 = function (context, ...args) {
    context = context || window
    context.__fn__ = this
    let result = context.__fn__(...args)
    delete context.__fn__
    return result
}

apply 的实现跟 call 类似,在这里直接给代码,代码来自于知乎 @郑航的实现:

Function.prototype.apply = function (context, arr) {
    var context = Object(context) || window;
    context.fn = this;

    var result;
    if (!arr) {
        result = context.fn();
    }
    else {
        var args = [];
        for (var i = 0, len = arr.length; i < len; i++) {
            args.push('arr[' + i + ']');
        }
        result = eval('context.fn(' + args + ')')
    }

    delete context.fn
    return result;
}

文章参考来https://github.com/mqyqingfen...

脚本宝典总结

以上是脚本宝典为你收集整理的JavaScript 深入之 call 和 apply 的模拟实现全部内容,希望文章能够帮你解决JavaScript 深入之 call 和 apply 的模拟实现所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。