SOURCE

Function.prototype.myCall = function (context) {
    if (typeof this !== 'function') {
        return new Error('type error')
    }
    let args = [...arguments].slice(1)
    let result

    context.fn = this
    result = context.fn(...args)
    delete context.fn
    return result
}

Function.prototype.myApply = function (context) {
    if (typeof this !== 'function') {
        return new Error('type error')
    }
    let result
    context.fn = this
    result = arguments[1] ? context.fn(...arguments[1]) :context.fn()
    delete context.fn
    return result
}

Function.prototype.myBind = function(context) {
    if (typeof this !== 'function') {
        throw new TypeError('type error')
    }    
    let args = [...arguments].slice(1)
    let fn = this

    return function Fn() {
        return fn.myApply(
            this instanceof Fn ? this : context,
            args.concat(...arguments)
        )
    }
}


const demo = {
    name: 'demo'
}

function fn(age,happy) {
    console.log(`${this.name}:${age}:${happy}`)
}

fn.myBind(demo, 88)('haha')
console 命令行工具 X clear

                    
>
console