bind call apply的实现

2020-01-13  本文已影响0人  Ernestfu

apply的实现

Function.prototype.myApply = function(tThis, params) {
    // 首先判断是不是被方法调用的
    if(typeof this !== "function") {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    // 这句话的巧妙之处在于,运用this的特性谁调用就指向谁
    // 如果tThis是空怎么办 暂时考虑兼容node和浏览器
    if(tThis === null || tThis === undefined) {
        tThis = typeof window !== "undefined" ? window : global;
    }
    tThis.fn = this;
    
    // 这个时候执行的this的指向就被改变为tThis了
    return params ? tThis.fn(...params) : tThis.fn();
}

call的实现

Function.prototype.myCall = function(params) {
    // 首先判断是不是被方法调用的
    if(typeof this !== "function") {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    let tThis = params;
    if(tThis === null || tThis === undefined) {
        tThis = typeof window !== "undefined" ? window : global;
    }
    tThis.fn = this;
    // 因为我么无法得知到底传进来了多少参数,所以这里就使用arguments来获取参数的量。
    let tParams = Array.prototype.slice.myApply(arguments, [1]);
    return tThis.fn(...tParams);
}

bind的实现

Function.prototype.myBind = function(params) {
//同上
    if(typeof this !== "function") {
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }
    let tThis = this;
    if(tThis === null || tThis === undefined) {
        tThis = typeof window !== "undefined" ? window : global;
    }

    let currentThis = params;
    let forParams = Array.prototype.slice.myCall(arguments, 1);
    // 获取原本this的原型链
    let cFn = function() {};
    // new 过来的时候这个this
    let fn = function () {
        let gThis = this instanceof fn ? this : currentThis;
        return tThis.apply(gThis, forParams.concat(Array.prototype.slice.myApply(arguments)));
    }

    if(this.prototype) {
        cFn.prototype = this.prototype;
        fn.prototype = new cFn();
        cFn.prototype = null;
        // 返回一个新的对象
    }
    return fn;
}
上一篇 下一篇

猜你喜欢

热点阅读