无法设置仅具有getter的属性(JavaScript ES6)

21

所以我有一个简单的Javascript类

class MyClass {
    constructor(x) {
        this.x = x === undefined ? 0 : x;
    }

    get x() {
        return this.x;
    }
}
当创建一个MyClass对象时, 我希望它的x被设置为传递的参数值。接下来,我不想让它可以被更改,因此我有意地没有创建set x()方法。
然而,我猜我可能错过了一些基本内容,因为这给我带来了“Cannot set property ... which only has getter”的错误。
如何在不创建setter方法的情况下分配x的值?

你不能这样做。属性必须是普通属性或者是getter/setter属性。(我想;需要查看规范) - Pointy
你的代码写法也会失败,因为getter中对this.x的引用将被理解为getter的函数调用,从而导致无限递归。 - Pointy
4个回答

33

这里有一些问题。

当你使用 get x() 创建 getter 时,会导致调用 getter 时结果为 this.x,由于你的 get x() 使用了 this.x,将会导致无限递归。

请在代码中将对 this.x 的引用替换为 this._x,像这样:

class MyClass {
    constructor(x) {
        this._x = x === undefined ? 0 : x;
    }

    get x() {
        return this._x;
    }
}

现在你的封装好的x,它现在是_x,将不会被误认为是通过this.x调用getter方法。


谢谢!这正是我所需要的! - user7446944

3
如果您希望一个实例属性是只读的,那么请将其设为不可写:

如果您想要一个实例属性是只读的,那么请将其设置为不可写:

class MyClass {
    constructor(x) {
        Object.defineProperty(this, "x", { value: x || 0 });
    }
}

一个属性可以是“简单”属性,就像所有属性在过去的日子里一样,也可以是getter/setter属性。

当一个属性是getter/setter属性时,所有对该属性的引用都通过getter或setter进行,包括在getter和setter函数内部。因此,为了存储该属性,您需要使用替代属性名称或(更好的)Symbol实例。

最初的回答:

属性可以是“简单”属性,也可以是getter/setter属性。

当属性是getter/setter属性时,所有对该属性的引用都通过getter或setter进行,包括在getter和setter函数内部。因此,为了存储该属性,你需要使用替代属性名称或(更好的)Symbol实例。


2

如果你想在类定义中创建一个不可变的属性 a,JavaScript提供了一种方法来实现,就是使用Object.defineProperty()方法。

最初的回答:

如果您想在类定义中创建一个不可变的属性a,则可以使用JavaScript提供的Object.defineProperty()方法来实现。

class MyClass {
  constructor(x) {
    Object.defineProperty(this, 'a', {
      enumerable: false,
      configurable: false,
      writable: false,
      value: x || 'empty'
    });
  }

}
let o = new MyClass('Hello');

console.log(o.a);
o.a = 'Will not change';
console.log(o.a);


0
class MyClass 
{
    constructor(x) {
        this.x = x === undefined ? 0 : x;
    }

    get() {
        return this.x;
    } 

    set(x) { return this.x = x;}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接