在Javascript中首次访问时初始化属性

时间:2014-05-07 06:46:48

标签: javascript getter

我想使用构造函数A创建一个对象,该对象具有属性x,该属性将在第一次访问时初始化。此外,类型A的任何对象都必须遵循相同的行为。我尝试过这样的事情:

function A() {
};

A.prototype = {
    get x() {
        delete this.x;  // try to delete getter
        this.x = 4;
        return 3;
    }
};

var a = new A();

console.log(a.x);  // 3
console.log(a.x);  // 3

我希望在控制台中看到34,而不是33

有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:0)

由于您总是在getter中返回值3,因此每次在控制台中获取此值都没有什么奇怪的。

我建议的解决方法是使用一个布尔值,表示以前是否曾访问x属性:

A.prototype = {
    inited: false,
    get x() {
        if (!this.inited) {
            this.inited = true;
            return 3;
        }
        return 4;
    }
};

Fiddle demo

答案 1 :(得分:0)

您可以使用Object.defineProperty()代替内联getter:

function A() {};


Object.defineProperty(A.prototype, "x", {
    get: function() {
        Object.defineProperty(this, "x", {
               enumerable: true,
             configurable: true,
                    value: 4
        });
        return 3;
    }    
});


var a = new A();

console.log(a.x); // 3
console.log(a.x); // 4

Object.defineProperty()允许我们重新配置"这个"具有"自己属性的对象(实例,而不是原型)"初次运行时的原始值。基本上,它在这个含义和#34;原型"之间存在歧义。这个意思"拥有"在getter-as-a-method中。可能有一种方法可以使用内联getter来实现,但ODP无论如何都更标准,它实际上可以按预期工作。

请记住,您可以将A.prototype.x设置为3,如果需要,请询问obj.hasOwnProperty(" x")vs if(obj.x)在本地/继承属性之间切换,所以你可能甚至不需要一个getter方法...

答案 2 :(得分:0)

虽然我接受了dandavis的答案,我发现它非常全面,但我找到了另一种可能的解决方案:

function A() {
    return {
        get x() {
            delete this.x;
            this.x = 4;
            return 3;
        }
    }
}

var a = new A();

console.log(a.x); // 3
console.log(a.x); // 4