SOURCE

/**
 * 手写实现 bind 方法
 * bind特点:
 * 1. 返回一个新函数,不会立即执行
 * 2. 永久绑定this上下文,还可以预置参数
 * 3. 返回的函数可以被new调用;new优先级高于绑定的ctx
 * @param {*} ctx - 绑定的this上下文
 * @param  {...any} args1 - 预置的前置参数
 * @returns {Function} 新函数
 */
Function.prototype.myBind = function(ctx, ...args1) {
    const originFn = this
    return function fn(...args2) {
        if(this instanceof fn) {
            // new调用,走构造函数创建实例;如果使用普通调用则会丢失原型链上变量
            return new originFn(...args1, ...args2)
        } else {
            // 普通调用,使用绑定上下文
            return originFn.apply(ctx, [...args1, ...args2])
        }
    }
}

const obj = {
    name: 'hello'
}
function fn() {
    console.log(this.name)
}
fn.myBind(obj)()

function Person(name) {
    this.name = name;
}
Person.prototype.getName = function() {
    return this.name
}
const boundPerson = Person.myBind({ name: 'test' }, '小明');
const p = new boundPerson();
console.log(p)
console.log(p.getName())
console.log(p.name); // 小明,不受绑定ctx影响
console 命令行工具 X clear

                    
>
console