使用带有Object.defineProperty的getter和setter

时间:2017-01-23 10:11:00

标签: javascript ecmascript-5

我想使用Object.defineProperty()将数据属性转换为访问者属性。请考虑导致Uncaught RangeError: Maximum call stack size exceeded错误

的代码
var c = { name: 'abcde'};
Object.defineProperty(c, 'name', {
    get: function() {
        return this.name; //causes stack overflow
    },
    set: function(x) {
       this.name = x; //causes stack overflow
        }
}); 
c.name="xyz";  
console.log(c.name);

我理解为什么这个错误会产生。 建议的解决方案之一是从getter和setter中删除'this',它似乎有效。

var c = { name: 'abcde'};
Object.defineProperty(c, 'name', {
    get: function() {
        return name; //removed this
    },
    set: function(x) {
       name = x; //removed this
        }
}); 
c.name="xyz";  
console.log(c.name);

发生了什么事?一般来说,我想问一下如何使用Object.defineProperty()将数据属性转换为访问者属性?

1 个答案:

答案 0 :(得分:1)

第二个代码实际上不起作用因为它使用名为name全局变量来存储值,而不是将其存储在对象c

如果window.name是浏览器中全局对象的默认属性,则不会被ES5"严格模式"拒绝。

更合适的修复方法是将值存储在词法范围的私有变量中:

var c = (function() {
    var obj = {};
    var name = "abcde";

    Object.defineProperty(obj, "name", {
        get: function() {
            return name;
        },
        set: function(x) {
            name = x;
        }
    });

    return obj;
})();