SOURCE

const A = {
    name: 'A',
    say(prefix, age){
        console.log(`${prefix},my name is ${this.name}, i'm ${age} years old`);
    }
}

const B = {
    name: 'B'
}

Function.prototype.myCall = function(target, ...args){
    const _target = target || window;  //规定没有target的时候指向window
    console.log(this)
    const symbolKey = Symbol();
    _target[symbolKey] = this;
    const res = _target[symbolKey](...args)
    delete _target[symbolKey]
    return res
}

A.say.myCall(B, 'hello', 12)

//apply与call的不同点在于apply传入的参数是一个数组
Function.prototype.myApply = function(target, args){
    const _target = target || window;
    const symbolKey = Symbol();
    _target[symbolKey] = this;
    const res = _target[symbolKey](...args)
    delete _target[symbolKey]
    return res
}

A.say.myApply(B, ['goodMorning', 14])

//bind本身是一个函数,返回的是一个函数,调用它的也是一个函数
Function.prototype.myBind = function(target, ...args){
    const _target = target || {};
    const symbolKey = Symbol();
    _target[symbolKey] = this;
    return function(...innerArgs){
        const res = _target[symbolKey](...args, ...innerArgs)
        return res;
    }
}

const bsay = A.say.myBind(B, 'hello')
bsay(18)
console 命令行工具 X clear

                    
>
console