js new call apply bind 的 原理

new

new 做了什么事?
1. 以 Object.protoype 为原型创建一个新对象

2. 以新对象为 this,执行函数的 [[call]]

3. 如果 [[call]] 的返回值是对象,那么,返回这个对象,否则返回第一步创建的新对象

function myNew(fn, ...args) {
  const obj = Object.create(fn.prototype);
  const ret = fn.call(obj, ...args);
  return ret instanceof Object ? ret : obj; 
}

call

实际上就是把方法挂在对象上,执行然后删除

Function.prototype.myCall = function(context, ...args) {
    if (typeof this !== 'function') {
        throw new TypeError('this is not a function')
    }
    context = context || window;
    context.fn = this;
    const ret = context.fn(...args);
    delete context.fn;
    return ret
}

apply

原理和call一样

Function.prototype.myApply = function (context, arg) {
    if (typeof this !== 'function') {
        throw new TypeError('this is not a function')
    }
    context = context || window;
    context.fn = this;
    let ret;
    if (arg) {
        ret = context.fn(...args);
    } else {
        ret = context.fn();
    }
    delete context.fn;
    return ret
}

bind

bind原理就是封一层闭包

function.prototype.myBind = function (context, ...bindArgs) {
    if (typeof this !== 'function') {
        throw new TypeError('this is not a function');
    }
    const _this = this;
    return function Fn(...execArgs) {
        const args = bindArgs.concat(execArgs);
        return _this.call(this instanceof Fn ? this : context, ...args);
    }
}
原文地址:https://www.cnblogs.com/amiezhang/p/6415862.html