繁体   English   中英

Javascript defineProperty和Object.keys返回困境

[英]Javascript defineProperty and Object.keys return dilemma

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

作为前提,我需要使用对象使用属性填充一个空对象。 defineProperty。 难题是我只想创建一个属性-[“ 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:超出最大调用堆栈大小” ,这是由于set在无限循环中一次又一次地调用相同的代码而触发的。 我想知道是否有任何解决此“ RangeError:最大调用堆栈...”问题 (可能重复)。 谢谢。

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

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

要解决您的问题,只需不使用accessor属性:

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"]

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

this._prop1 = value;

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

Object.defineProperty(myObj, "_prop1", { enumerable:false });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM