Pregunta

/**
 * @author paula
 */
var myObj = {};
Object.defineProperty(myObj, "prop1", {
           get: function(){return this._prop1;}, 
           set:function(value){this._prop1 = value;}, 
           enumerable:true});

Object.keys(myObj)    // Note that returns ["prop1"]
myObj.prop1 = "Hello"; // call set
Object.keys(myObj);    // Returns ["prop1", "_prop1"]
myObj          // Object {prop1: "Hello", _prop1: "Hello"}

I have as a prerequisite an empty object to be populated with properties using Object. defineProperty. The dilemma is that I wanted to create only one property - ["prop1"] and in the example above, based on what Object.keys() returns, it looks like that 2 properties were created - ["prop1", "_prop1"].

Question: What is the name for "prop1" - is a property or it's kind of pseudo-property ? Is it correct to be used the name property for both "prop1" and "_prop1" ?

I also tried this solution:

var myObj1 = {};
Object.defineProperty(myObj1, "prop1", {
             get: function(){return this.prop1;}, 
             set:function(value){this.prop1 = value;}, 
             enumerable:true});
myObj1.prop1= "Bye" 

and got this error: "RangeError: Maximum call stack size exceeded" which is triggered because set calls the same code over and over again in an infinite loop. I was wondering if there is any solution to this "RangeError: Maximum call stack ..." problem ? (possible duplicate). Thanks.

¿Fue útil?

Solución

Question: What is the name for "prop1" - is a property or it's kind of pseudo-property ? Is it correct to be used the name property for both "prop1" and "_prop1" ?

Yes, both are properties. prop1 is an accessor property (with getters/setters) while _prop1 is a data property (simple, writable value).

To solve your problem, just don't use an accessor property:

Object.defineProperty(myObj, "prop1", {
//  value: undefined,
    writable: true,
    enumerable: true
});

If you need an accessor property for some reason, store the value either in a closure variable or in a non-enumerable "hidden" property:

(function() {
    var value;
    Object.defineProperty(myObj, "prop1", {
        get: function(){ return value; }, 
        set: function(v){ value = v; }, 
        enumerable:true
    });
})();

Object.defineProperties(myObj, {
    "_prop1": {
         enumerable: false,
         writable: true
    },
    "prop1": {
        get: function(){ return this._prop1; }, 
        set: function(value){ this._prop1 = value; }, 
        enumerable:true
    }
});
Object.keys(myObj) // ["prop1"]

Otros consejos

When you do this in your setter:

this._prop1 = value;

you're creating the "_prop1" property. If you don't want it to be enumerable, define it that way:

Object.defineProperty(myObj, "_prop1", { enumerable:false });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top