背景
我有一个原型(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/