我有这个构造函数对象:
function Bindable(obj) {
var prop;
for (prop in obj) {
this.__defineGetter__(prop, function () {
return obj[prop];
});
this.__defineSetter__(prop, function (val) {
obj[prop] = val;
});
}
}
这样被称为:
var model = new Bindable({
name: 'Dave',
level: 10,
strength: 5
});
如果我console.log(model)
,则输出为:
Bindable { name=5, level=5, strength=5 }
为什么将相同的值分配给构造函数中的每个属性?
答案 0 :(得分:2)
您正在创建一个闭包,该闭包在getter / setter函数执行时进行评估,而不是在定义它们时进行评估。在执行时,prop
具有在执行循环期间分配的最后一个值。您需要避免在prop
上创建闭包。一种方法是使用IIFE。而不是使用这个参数:
function () {
return obj[prop];
}
使用
(function(p) {
return function() {
return obj[p];
};
}(prop));
答案 1 :(得分:1)
作为替代方案,这应该适合你。
@ Same principle as explained但现在我们有一个可重复使用的函数createGetterSetter
,它使用ECMA5方法Object.defineProperty
来定义getters and setters,正如@ Benjamin Gruenbaum所指出的那样。
它也使用您使用的ECMA5 Object.keys
而不是for..in
。
我认为这比Ted建议的解决方案(每个人都有他们的偏好)更为整洁。
我不确定改进空间的唯一部分是var self = this;
的Javascript
/*jslint maxerr: 50, indent: 4, browser: true */
/*global console */
(function () {
"use strict";
function createGetterSetter(object, map, prop) {
Object.defineProperty(object, prop, {
get: function () {
return map[prop];
},
set: function (val) {
map[prop] = val;
}
});
}
function Bindable(obj) {
var self = this;
Object.keys(obj).forEach(function (prop) {
createGetterSetter(self, obj, prop);
});
}
var model = new Bindable({
name: 'Dave',
level: 10,
strength: 5
});
console.log(model.name, model.level, model.strength);
}());
输出
Dave 10 5
上