如您所知,我们可以使用defineProperty()在JS中定义getter和setter。尝试使用defineProperty()扩展类时,我一直受困。

这是示例代码:

我有一个必须添加到对象的字段数组

fields = ["id", "name", "last_login"]

我也有一个类(class)将被修改
var User = (function(){
    // constructor
    function User(id, name){
        this.id     = id
        this.name   = name
    }
    return User;
})();

还有一个函数,它将使用defineProperty()将字段添加到类中
var define_fields = function (fields){
    fields.forEach(function(field_name){
        var value = null
        Object.defineProperty(User.prototype, field_name, {
            get: function(){ return value }
            set: function(new_value){
                /* some business logic goes here */
                value = new_value
            }
        })
    })
};

运行define_fields()之后,我将字段输入User实例中
define_fields(fields);
user1 = new User(1, "Thomas")
user2 = new User(2, "John")

但是这些属性的值是相同的
console.log(user2.id, user2.name) // 2, John
console.log(user1.id, user1.name) // 2, John

在这种情况下,有什么方法可以使defineProperty()正常工作?
如果我了解问题所在,那就是value该类的每个实例,但我不知道如何解决它。提前致谢
为您的答案。

UPD:
这种方式抛出“RangeError:超出最大调用堆栈大小”
var define_fields = function (fields){
    fields.forEach(function(field_name){
        Object.defineProperty(User.prototype, field_name, {
            get: function(){ return this[field_name] }
            set: function(new_value){
                /* some business logic goes here */
                this[field_name] = new_value
            }
        })
    })
};

最佳答案

请不要实现任何其他版本,因为它将占用您应用程序中的所有内存:

var Player = function(){this.__gold = 0};

Player.prototype = {

    get gold(){
        return this.__gold * 2;
    },



    set gold(gold){
        this.__gold = gold;
    },
};

var p = new Player();
p.gold = 2;
alert(p.gold); // 4

如果实例化了10000个对象:
  • 用我的方法:内存中将只有2个函数;
  • 使用其他方法:存储器中的10000 * 2 = 20000个函数;
  • 09-25 21:10