javascript - 在 Javascript 中将对象原型(prototype)函数绑定(bind)到对象

标签 javascript prototype call this bind

背景

我有一个原型(prototype)对象,它有数十个函数,可以从如下列表中访问信息:

var prototype_object = {
  yellow: function(list) { return list[this.type+'_yellow']; },
  green: function(list) { return list[this.type+'_green']; },
  // ... 50 more functions here
}

“this.type”应该来自在函数中分配原型(prototype)的对象:

function accessor(type) {
    var widget = Object.create(prototype_object);
    widget.type = type;
    return widget;
}

我有一个中央信息列表,因此现在我可以调用:

var access_foo = accessor('foo'); // Create the accessor
access_foo.green(list); //Find 'foo_green' in the list

问题

这些访问器 fxns 被传递到应用程序的不同区域,并在分配给新对象后调用。因此,原型(prototype)函数中的“this”被重新分配(如 JavaScript 中的预期)并导致未定义的类型。

“SO BIND IT”:我们可以绑定(bind)到函数来设置“this”,这将创建新函数。我无法在几十个地方为数百种对象类型实例化 60 个新函数。

“调用它”:调用需要我将原始访问器作为“this”传递,但正如我所说,access_foo.green 会传递到应用程序中的其他位置,并且无法在调用时引用回 access_foo。

“更改 PROTOTYPE_OBJECT PARAMS”:应用程序的编写方式不是一个选项。

最后,我需要一个知道其类型并共享对大量函数的访问权限的对象。我是否正确地说,没有办法创建可以在上下文之外调用的自定义访问器,而不让它们全部实例化/绑定(bind)到全套可能的原型(prototype)函数?

最佳答案

您似乎已经排除了所有可能的解决方案。如果您想要一个解决方案,您将必须适应使用其中一个选项。如果您在很多地方传递访问器函数,并且希望它们永久绑定(bind)到您的对象(这样您就不必也传递该对象),那么您将不得不改变您的工作方式。

最干净的方法是在构造函数中定义方法,并让这些方法使用构造函数局部变量作为对象引用,并依赖构造函数闭包而不是使用 this。然后,即使 this 是错误的,它们仍然可以工作。为此,您必须重新创建对象。

您还可以重新定义所有方法以预先绑定(bind)自身。我将展示这两个选项的代码示例。

这里是关闭方法:

function myObj() {
    var self = this;
    self.prop1 = "foo";

    // define all methods in here and use self instead of this
    self.method1 = function() {
        console.log(self.prop1);
    }
}

var x = new myObj();
var m = x.method1;
m();

并且,这是预绑定(bind)方法,同时尽可能少地更改现有代码:

var prototype_object = {
  yellow: function(list) { return list[this.type+'_yellow']; },
  green: function(list) { return list[this.type+'_green']; },
  // ... 50 more functions here
}

function accessor(type) {
    var widget = Object.create(prototype_object);
    widget.type = type;
    // reassign prototype methods to the actual object and make them pre-bound
    // to this particular instance
    for (var method in prototype_object) {
       if (typeof method === "function") {
           // assign pre-bound method to the instance
           widget[method] = widget[method].bind(widget);
       }
    }
    return widget;
}

这个版本是前一个版本的优化版本,根本没有将新方法放在原型(prototype)上:

var prototype_object = {
  yellow: function(list) { return list[this.type+'_yellow']; },
  green: function(list) { return list[this.type+'_green']; },
  // ... 50 more functions here
}

function accessor(type) {
    var widget = {};
    widget.type = type;
    // reassign prototype methods to the actual object and make them pre-bound
    // to this particular instance
    for (var method in prototype_object) {
       if (typeof method === "function" && prototype_object.hasOwnProperty(method)) {
           // assign pre-bound method to the instance
           widget[method] = prototype_object[method].bind(widget);
       }
    }
    return widget;
}

关于javascript - 在 Javascript 中将对象原型(prototype)函数绑定(bind)到对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28637438/

相关文章:

javascript - “this”在 JavaScript 类方法中未定义

javascript - 在没有调用函数的情况下返回如何在 Javascript 中工作?

Python 函数调用真的很慢

javascript - 为什么这个下拉菜单会移动另一个元素?

javascript - 选择 ng-grid 内的所有复选框

适用于 iPad 的 Javascript IDE

javascript - 使用 JavaScript/JQuery,当相关元素从下方经过时,使导航链接突出显示?

javascript - 用另一个原型(prototype)扩展原型(prototype)

javascript - 模拟 'class' 时,为什么要在 .prototype 属性中而不是在构造函数本身中设置方法?

javascript - 如何在 Firebase 身份验证函数中调用函数?