Javascript 使用getter和setter将参数复制到对象实例

Javascript 使用getter和setter将参数复制到对象实例,javascript,object,constructor,getter-setter,ecmascript-5,Javascript,Object,Constructor,Getter Setter,Ecmascript 5,我有一个构造函数对象: function Bindable(obj) { var prop; for (prop in obj) { this.__defineGetter__(prop, function () { return obj[prop]; }); this.__defineSetter__(prop, function (val) { obj[prop] = val;

我有一个构造函数对象:

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
});
如果I
console.log(model)
,则输出为:

Bindable { name=5, level=5, strength=5 }

为什么为构造函数中的每个属性分配相同的值?

您正在创建一个闭包,该闭包在执行getter/setter函数时进行计算,而不是在定义它们时进行计算。执行时,
prop
具有循环执行期间分配的最后一个值。您需要避免在
prop
上创建闭包。一种方法是使用一个。不要使用此参数:

function () {
    return obj[prop];
}
使用


作为替代方案,这应该对您有效

借@

但是现在我们有了一个可重用的函数
createGetterSetter
,它使用ECMA5方法来定义,正如@所指出的

它还使用ECMA5,而不是您使用的中的

我认为这比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

上,为什么在标准的
对象上使用非标准的和不推荐的
\uuuuu defineProperty\uuuuuuuuu
?因为这对我来说是新闻。这似乎是正确的。
.bind
ing处理程序而不是iLife难道不能提供一个更简单的解决方案吗?我不明白
.bind
ing在这种情况下是如何工作的。请解释一下。@davidkennedy85。您没有显式地包装在闭包中,而是在绑定中设置
p
的值。@BenjaminGruenbaum-您仍然需要一个函数作为
bind
的参数。您还需要提供一个
this
参数(可能是
null
),这只会增加代码混乱。像David一样,我看不出
bind
是如何简化的。当前代码:
(函数(p){return function(){return obj[p];};}(prop))。新代码
函数(p){returnobj[p]}.bind(null,prop)。这是一个非常优雅的解决方案。我将保留Ted的答案作为选择答案,因为它只是说明问题所在。
Dave 10 5