javascript Power .bind()代码战任务

h6my8fg2  于 2023-03-16  发布在  Java
关注(0)|答案(1)|浏览(100)

有一个任务是创建一个自定义绑定,它允许你无限次地修改绑定内容。我创建了这样一个函数,它在本地为我工作。但是它没有通过代码战的测试。告诉我可能是什么问题。
链接到此任务:https://www.codewars.com/kata/5388a9d60b24c52f4c000b5f/train/javascript
代码:

Function.prototype.bind = function (context) {
      if (!globalThis.func) {
        globalThis.func = this;
      }
      return function (...arg) {
        globalThis.func.call(context, ...arg);
      };
    };

我用下面的代码测试了这个函数:

var func = function (a) {
      console.log("Argument is:", a);
      console.log("this = ", this);
      return this.prop;
    };
    var obj1 = { prop: 1 },
      obj2 = { prop: 2 };

    func = func.bind(obj1);
    func("Arg1");

    func = func.bind(obj2);
    func("Arg2");
bpsygsoo

bpsygsoo1#

您的解决方案修改了一个全局变量,该变量应该是所有将要使用.bind()的函数的全局名称。即使在理论上,这也是行不通的。
使用Map(或WeakMap,您可以选择)将每个绑定函数链接到其原始函数。

(() => { // Closure function
    const bind = Function.prototype.bind; // Original bind
    const map = new Map(); // Map<BoundFunction, Function>

    Function.prototype.bind = function(context) {
        if (!map.has(this)) { // Not found in map => not bound.
            let bound = bind.call(this, context);
            map.set(bound, this);
            return bound;
        } else {
            let unbound = map.get(this);
            return bind.call(unbound, context);
        }
    };
})();

请注意,这不适用于IIFE生效之前绑定的函数:

function foo() {
  return this.foo;
}

foo = foo.bind({ foo: 0 });

(() => { /* ... */ })();

console.log(foo()); // 0
console.log(foo.bind({ foo: -1 })()); // 0

试试看:

(() => {
  const bind = Function.prototype.bind;
  const map = new Map();

  Function.prototype.bind = function(context) {
    if (!map.has(this)) {
      let bound = bind.call(this, context);
      map.set(bound, this);
      return bound;
    } else {
      let unbound = map.get(this);
      return bind.call(unbound, context);
    }
  };
})();

function func() {
  return this.prop;
};

console.log(func.bind(globalThis)()); // undefined

func = func.bind({ prop: 1 });
console.log(func()); // 1

func = func.bind({ prop: 2 });
console.log(func()); // 2

(() => {
  // Also works with locals
  function foo() {
    return this.foo
  }

  const foo1 = foo.bind({ foo: 3 });
  const foo2 = foo.bind({ foo: 4 });

  console.log(foo1());
  console.log(foo2());
})();

相关问题