js中call和apply的实现

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;

}

Function.prototype.call3 = function (context) {

    let context = context || window;

    context.fn = this;

    let args = [...arguments].slice(1)

    let result = context.fn(...args)

    delete context.fn

    return result;

}

Function.prototype.myApply = function (context) {

   if (typeof this !== 'function') {

      throw new TypeError('Error')

   }

   if (context === null || context === undefined) {

        context = window     // 指定为 null 和 undefined 的 this 值会自动指向全局对象(浏览器中为window)

    } else {

        context = Object(context) // 值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的实例对象

    }

    context.fn = this

    let result 

    //判断是否存在第二个参数

    //如果存在就将第二个参数也展开

    if(arguments[1]) {

        result = context.fn(...arguments[1])

    } else {

        result = context.fn()

    }

    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.call(null); // 2

console.log(bar.call3(obj, 'Cherry', 18));

console.log(bar.myApply(obj, ['Cherry', 18]));

你可能感兴趣的:(js中call和apply的实现)