0
/**
 * @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"}

作为先决条件,我有一个空对象,要使用 Object.properties 填充属性。定义属性。困境是我只想创建一个属性 - ["prop1"],在上面的示例中,根据 Object.keys() 返回的内容,看起来创建了 2 个属性 - ["prop1", "_prop1" ]。

问题:“prop1”的名称是什么 - 是一种属性还是一种伪属性?将 name 属性用于 "prop1" 和 "_prop1" 是否正确?

我也试过这个解决方案:

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

并收到此错误:“RangeError: Maximum call stack size exceeded”被触发,因为 set 在无限循环中一遍又一遍地调用相同的代码。我想知道这个“RangeError:最大调用堆栈......”问题是否有任何解决方案?(可能重复)。谢谢。

4

2 回答 2

6

问题:“prop1”的名称是什么 - 是一种属性还是一种伪属性?将 name 属性用于 "prop1" 和 "_prop1" 是否正确?

是的,两者都是属性。prop1是一个访问器属性(带有 getter/setter),_prop1而是一个数据属性(简单的可写值)。

要解决您的问题,请不要使用访问器属性:

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

如果出于某种原因需要访问器属性,请将值存储在闭包变量或不可枚举的“隐藏”属性中:

(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"]
于 2014-03-27T16:12:10.850 回答
1

当您在设置器中执行此操作时:

this._prop1 = value;

您正在创建“_prop1”属性。如果您不希望它是可枚举的,请以这种方式定义它:

Object.defineProperty(myObj, "_prop1", { enumerable:false });
于 2014-03-27T16:09:16.407 回答