bind函数实现 及连续调用

574 阅读2分钟

在Javascript中, bind函数允许一个对象绑定到函数上,并在调用时指定该对象作为函数上下文。这通常用于创建一个新的函数,该函数会与原始函数共享相同的实现代码,但是在执行时会默认使用指定的绑定对象作为其上下文。以下是 bind() 函数的实现示例:

    Function.prototype.bind = function(obj) {
        var originalFunction = this; // 获取原始函数
        // 获取除了绑定对象外的所有函数参数
        var args = Array.prototype.slice.call(arguments, 1);
        return function() {
            // 将绑定对象和所有函数参数合并到一个数组中
            var combinedArgs = args.concat(Array.prototype.slice.call(arguments)); 
            // 调用原始函数并将绑定对象作为执行上下文传递
            return originalFunction.apply(obj, combinedArgs); 
        }
    }

使用该实现,您可以调用以下代码:

    var obj = {
      name: 'Peter',
      age: 25,
      greet: function(greeting) {
        console.log(greeting + ', my name is ' + this.name + ' and I am ' + this.age + ' years old.');
      }
    };
    
    // 将 obj 对象绑定到 greet 函数上,并传递 'Hello' 作为参数
    var boundFunc = obj.greet.bind(obj, 'Hello'); 
    boundFunc(); // 输出: 'Hello, my name is Peter and I am 25 years old.'

在上述示例中,我们创建了一个名为 obj 的对象,并且该对象具有一个 greet() 方法,该函数将指定的字符串参数与对象属性组合。我们然后使用 bind() 函数将 greet() 方法绑定到 obj 对象上,并将 'Hello' 作为第一个参数传递。最后,我们使用返回的函数 boundFunc() 调用 obj.greet() 并检查打印输出是否正确。

JS 中 bind 函数连续调用的问题

    let a = 'a-window'
    const o = {
      a: 'a-o'
    }
    const c = {
      a: 'a-c'
    }
    function test() {
      console.log(this.a)
    }
    test.bind(o).bind(c)()

上述执行结果是 a-o 而不是 a-c 原因是,在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。