具有getter / setter

时间:2015-09-25 20:08:24

标签: javascript

我正在搞乱一些" classic"继承和我遇到了一个问题。我正在使用Object.defineProperty()向我的LivingThing"类"添加属性。我想要一个默认值,以及一个属性getter / setter。

http://jsfiddle.net/fmpeyton/329ntgcL/

我遇到了以下错误:

Uncaught TypeError: Invalid property.  A property cannot both have accessors and be writable or have a value, #<Object>

为什么我会收到此错误?使用Object.defineProperty()获取属性的默认值和getter / setter的最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

使用函数作用域变量来支持已定义的属性并将该变量的初始值设置为默认值:

function LivingThing(){
    self = this;
    var isAlive = true;

    Object.defineProperty(self, 'isAlive', {
        get: function(){
            return isAlive;
        },
        set: function(newValue){
            isAlive = newValue;
        },
        configurable: true
    });

    self.kill = function(){
        self.isAlive = false;
    };
}

http://jsfiddle.net/329ntgcL/5/

writable不是必需的,因为你有一个二传手。这就是造成你的错误的原因。您可以使用值/可写(数据描述符)或获取/设置(访问者描述符)。

因此,当您致电var l = new LivingThingl.isAlive == true并致电l.kill()后,l.isAlive == false

答案 1 :(得分:1)

你的getter / setter对提供了一个计算属性,如果你需要存储,你可以(并且应该)使用不动产来支持它:

self._isAlive = true;
Object.defineProperty(self, 'isAlive', {
    get: function(){
        return this._isAlive;
    },
    set: function(newValue){
        this._isAlive = newValue;
    },
    writable: true,
    configurable: true
});

据推测,在那里设置一些逻辑来证明setter / getter与常规属性的合理性。 Setter用于包装属性访问。

答案 2 :(得分:1)

如果没有setter和getter,只需将其分配给原型即可定义默认值:

LivingThing.prototype.isAlive = true

var o = new LivingThing()

console.log(o.isAlive) // true

为了清楚起见,在LivingThing实例上更改该属性将为该实例创建一个属性,而不是更改其__proto__中的值。

o.isAlive = false

console.log(new LivingThing().isAlive) // still true