这对于 JavaScript 绑定方法的 Polyfill 来说是一个可接受的解决方案吗?

Would this be an acceptable solution for a Polyfill for JavaScript bind method?

首先,我将当前传递的上下文复制到 dummy 中。 然后我添加一个方法 fn 作为当前传递的函数。 虚拟对象存在于闭包中。 最后,我将 return 一个使用最初传递的参数执行 dummy.fn 的函数。

Function.prototype.bind2 = function(context, ...args){
    var dummy = {...context}
    dummy.fn = this
    return function(){
        return dummy.fn(...args)
    }
}

编辑 1:在对新虚拟对象的第一个建议之后,我将其更改为以下内容

Function.prototype.bind2 = function(context, ...args){
    var dummy = Object.create(context)
    dummy.fn = this
    return function(){
        return dummy.fn(...args)
    }
}

编辑 2:对于扩展运算符修复,我使用了 eval:

Function.prototype.bind2 = function(){
    var args = arguments;
    var dummy = Object.create(args[0]);
    dummy.fn = this;
    return function(){
                return eval('dummy.fn('+Object.values(args).slice(1,).join(',')+')') 
           } 
}

不对,乍一看,有几个问题:

  • bind 将在传递的上下文中调用方法,而不是它的副本——您的版本使得绑定函数不可能直接影响上下文

  • 您使用的复制对象的方法会从其原型中删除对象,以及它可能具有的任何魔法

  • bind 也将允许函数接受未绑定的附加参数

  • 任何需要 bind 填充的环境都无法处理 ... 扩展语法。

Function.prototype.bind2 = function(context, ...args){
    var dummy = {...context}
    dummy.fn = this
    return function(){
        return dummy.fn(...args)
    }
}

let obj = Object.create({
  name: "an obj",
  getName: function() { return this.name; },
  setFoo: function() { this.foo = 42; },
  showBarBaz: function(bar, baz) { console.log(bar, baz) }
});
obj.setFoo.bind2(obj)();                 // does not set `obj.foo`
console.log(obj);
console.log(obj.getName.bind2(obj)());   // no access to prototype
obj.showBarBaz.bind2(obj, "bar")("baz"); // does not pass "baz"

obj.setFoo.bind(obj)();                  // sets `obj.foo`
console.log(obj);
console.log(obj.getName.bind(obj)());    // full access to prototype
obj.showBarBaz.bind(obj, "bar")("baz");  // passes "baz"