As you know we can define getters and setters in JS using defineProperty()
. I've been stuck when trying to extend my class using defineProperty()
.
Here is an example code:
I have an array of fields which must be added to a object
fields = ["id", "name", "last_login"]
Also I have a class which will be modified
var User = (function(){
// constructor
function User(id, name){
this.id = id
this.name = name
}
return User;
})();
And a function which will add fields to the class using 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
}
})
})
};
After running define_fields()
I have my fields in the instance of the User
define_fields(fields);
user1 = new User(1, "Thomas")
user2 = new User(2, "John")
But the values of these properties are identical
console.log(user2.id, user2.name) // 2, John
console.log(user1.id, user1.name) // 2, John
Is there any way to make defineProperty()
work properly in this case?
If I understand the problem is with value
which becomes identical for
each instance of the class but i can't realise how to fix it. Thanks in advance
for your answers.
UPD: This way throws "RangeError: Maximum call stack size exceeded"
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
}
})
})
};
Please don't implement any other version because it will eat all your memory in your app:
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
If 10000 objects are instantiated: