使用 Class 声明原型默认值的 ecmascript 6 语法

awe*_*wei 7 javascript prototype ecmascript-6 es6-class

在 javascript 中创建类时,您可以通过访问函数的prototype.

    function Foo() {
    }
    Foo.prototype.get = function() {
        return this._value;
    }
    Foo.prototype._value = 'foo value';
    var foo = new Foo();
    console.log(foo.get()); // logs "foo value"
Run Code Online (Sandbox Code Playgroud)

如何使用 ecmascript 6 达到类似的效果class

    // this doesn't work
    class Bar {
        get() {
            return this._value;
        }
        // how to declare following default value properly?
        _value: "bar value"
    }
    var bar = new Bar();
    console.log(bar.get()); // logs undefined
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 5

class语法只允许您定义方法,但它仍然只是使用.prototype对象创建构造函数。您可以像 ES5 中一样设置默认值:

// this does work
class Bar {
    get() {
        return this._value;
    }
}
Bar.prototype._value = 'foo value';
var bar = new Bar();
console.log(bar.get()); // logs 'foo value'
Run Code Online (Sandbox Code Playgroud)

当然,您可能只想创建并初始化一个实例属性:

// this does work
class Bar {
    constructor() {
        this._value = 'foo value';
    }
    get() {
        return this._value;
    }
}
var bar = new Bar();
console.log(bar.get()); // logs 'foo value'
Run Code Online (Sandbox Code Playgroud)

另一个相当常见的解决方案是使用 getter,它将在原型上定义,当然它的缺点是每次访问属性时都会创建值:

class Bar {
    get() {
        return this._value;
    }
    get _value() {
        return 'foo value';
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您坚持仅使用class语法,ES2022 将具有静态块,这些静态块也可能被滥用来创建原型属性:

class Bar {
    get() {
        return this._value;
    }
    static {
        this.prototype._value = 'foo value';
    }
}
Run Code Online (Sandbox Code Playgroud)