TypeScript属性中的readonly和get之间有什么区别?

kri*_*gar 7 javascript typescript

在TypeScript中声明一个属性readonly与通过a创建它之间在功能上有区别get()吗?两者的行为相同,但最好知道除偏好之外是否还有理由使用一个。

Ber*_*rgi 7

每次访问属性时都会再次评估 getter,并创建一个新值。这是一个重要的功能差异,因为该行为通常不是您想要的:

class Example {
    get foo(): object {
        return {};
    }
    readonly bar: object = {};
}
const example: Example = new Example;
console.log(example.foo === example.foo); // false
console.log(example.bar === example.bar); // true
Run Code Online (Sandbox Code Playgroud)

实现细节见@TJCrowder的优秀回答,这里不再赘述。

  • 但在大多数情况下,这是一个非常重要的区别。 (2认同)

T.J*_*der 6

它与生成的JavaScript有所不同:getter将是访问器属性(例如,函数),该readonly属性将是data属性。这个:

class Example {
    get foo(): string {
        return "foo";
    }
    readonly bar: string = "bar";
}
Run Code Online (Sandbox Code Playgroud)

如果您定位到ES2015 +,则转换为此:

"use strict";
class Example {
    constructor() {
        this.bar = "bar";
    }
    get foo() {
        return "foo";
    }
}
Run Code Online (Sandbox Code Playgroud)

住在操场上

或针对此目标(如果您针对ES5 +):

"use strict";
var Example = /** @class */ (function () {
    function Example() {
        this.bar = "bar";
    }
    Object.defineProperty(Example.prototype, "foo", {
        get: function () {
            return "foo";
        },
        enumerable: true,
        configurable: true
    });
    return Example;
}());
Run Code Online (Sandbox Code Playgroud)

住在操场上

请注意,尽管TypeScript认为是bar只读的,但在运行时并没有什么强制实施。foo另一方面,即使在运行时,它也是只读的。(尽管您确实愿意,但可以Object.defineProperty通过重新配置属性来击败它。)