0
点赞
收藏
分享

微信扫一扫

JavaScript 手写 call,apply

蓝哆啦呀 2022-01-09 阅读 96
Function.prototype.call = function (context) {
    // null, undefined, empty : window
    // number, String, Boolean : 包装类型 Object(1) Object(‘1’) Object(true)
    // object : object
    context = context ? Object(context) : window;

    // 在函数变为 context 对象的方法,执行对象上下文。
    context.fn = this;

    // 创建数组变量接收。
    var args = [];

    // [‘argument[1]’, ‘argument[2]’, ‘argument[3]’...] 格式
    for (var i = 1; i < arguments.length; i++) {
        args.push('argument[' + i + ']');
    }

    // 先字符串拼接,函数 args 会转为基本类型,调用 toString 方法,返回 argument[1],argument[2]…
    // 得到 ‘context.fn(argument[1], argument[2]…)’;
    // 在用 eval 在当前函数作用域进行解析字符串,执行当前语句。 Context.fn(argument[1], argument[2],…);
    var result = eval('context.fn(' + args + ')');

    // 用完之后删除对象上自定义的方法。
    delete context.fn;

    // 返回 函数执行的返回值。
    return result;
}


Function.prototype.apply = function myApply(context, arr) {
    // null, undefined, empty : window
    // number, String, Boolean : 包装类型 Object(1) Object(‘1’) Object(true)
    // object : object
    context = context ? Object(context) : window;

    // 在函数变为 context 对象的方法,执行对象上下文。
    context.fn = this;

    var result = null;

    // 传入了数组参数
    if (!arr) {

        // 没有参数可以直接在 context 下调用函数
        result = context.fn();

    } else {

        // 创建数组变量接收。
        var args = [];

        // [‘argument[1]’, ‘argument[2]’, ‘argument[3]’...] 格式
        for(var i = 0; i < arr.length; i++) {
            args.push('arr[' + i +']');
        }

    // 先字符串拼接,函数 args 会转为基本类型,调用 toString 方法,返回 arr[0],arr[1]…
    // 得到 ‘context.fn(arr[0], arr[1]…)’;
    // 在用 eval 在当前函数作用域进行解析字符串,执行当前语句。 Context.fn(arr[0], argument[1],…);
        result = eval('context.fn(' + args +')');
    }

    // 用完之后删除对象上自定义的方法。
    delete context.fn;

    // 返回 函数执行的返回值。
    return result;
}
}
举报

相关推荐

0 条评论