• 手写实现 js 中的bind,并实现 softBind


    // bind会返回一个硬绑定的新函数,新函数会使用指定的第一个thisCtx去调用原始函数,并将其它参数传给原始函数。 硬绑定会降低函数的灵活性,在绑定之后不能通过显式或硬绑定的方式改变this,只能通过new改变
    // softBind 会对指定的函数进行封装,首先检查调用时的 this,如果 this 绑定到全局对象或者 undefined,那就用指定的thisCtx 去调用函数,否则不会修改 this
    Function.prototype.myBind = function (context, ...args) {
        const self = this;
        const fn = function (...newArgs) {
            console.log("this", this); //  链式调用的时候 { a: 6 }
            console.log("context", context); //{ a: 2 }
            // 优先判断是否来自new 调用之后的实例,是的话 this 不变
            self.apply(this instanceof fn ? this : context, args.concat(newArgs));
        };
        fn.prototype = Object.create(this.prototype);
        return fn;
    };
    function f1(b) {
        console.log(this.a, b);
    }
    let fb11 = f1.myBind({ a: 1 }, 10);
    let bindFn1 = new fb11(); // undefined 10   因为 new 调用优先级高于 bind 改变的this 指向
    let fb22 = f1.myBind({ a: 2 }, 10);
    fb22(); // 2,10
    let fb33 = f1.myBind({ a: 3 }, 10);
    fb33(); // 3,10
    let fb66 = fb22.myBind({ a: 6 }, 10)(); // 2,10
    // fb66(); // 2,10
    // 结论:bind方法链式调用,都以第一次bind绑定为准,所以叫硬绑定,原理为 下一次 调用bind的方法为上一个bind方法返回的闭包,已经将 context、args 存储好并固定返回了
    // 参考链接:https://juejin.cn/post/6921897996258918413
    // bind方法分别多次调用,各自都可绑定成功
    console.log("=================");
    // softBind   globalThis 代表获取当前环境下的全局对象
    Function.prototype.softBind = function (context = globalThis, ...args) {
        const self = this;
        const fn = function (...newArgs) {
            // new 的时候和链式调用 softBind 的时候打印
            if (this !== globalThis) {
                console.log("this", this); //  链式调用的时候 { a: 6 }
                console.log("context", context); //{ a: 2 }
            }
            self.apply(
                this instanceof fn ? this : !this || this === globalThis ? context : this,
                args
            );
        };
        fn.prototype = Object.create(this.prototype);
        return fn;
    };
    let fs22 = f1.softBind({ a: 2 }, 10);
    fs22(); // 2 10
    let fs33 = f1.softBind({ a: 3 }, 10);
    fs33(); // 3 10
    let fs66 = f1.softBind({ a: 2 }, 10).softBind({ a: 6 }, 10);
    fs66(); //6 10
    let fs11 = f1.softBind({ a: 1 }, 10);
    let softbindFn1 = new fs11(); // undefined 10   因为 new 调用优先级高于 bind 改变的this 指向
  • 相关阅读:
    C++中析构函数为什么要是虚函数
    依赖注入(IOC)
    ParseInt()与NaN()
    仿windows关机效果
    类似Tab的效果
    飞来飞去的广告
    Sql Server 三种连接
    JS日期处理
    绚丽的注册效果
    JS图片自动切换
  • 原文地址:https://www.cnblogs.com/beileixinqing/p/16597249.html
Copyright © 2020-2023  润新知