JavaScript ES6 class 只有吸气剂
JavaScript ES6 class with getters only
请问,在ES6中,如何只使用getter而没有setter(readOnly)属性?为什么 Webstorm 告诉我这是一个错误?
这是我的代码:
class BasePunchStarter {
constructor(id,name,manufacturer,description,genres,targetPrice) {
if (new.target==BasePunchStarter) {
throw new TypeError("BasePunchStarter class cannot be instantiated directly!");
}
if (typeof id =="number") {
// noinspection JSUnresolvedVariable
this.id = id;
} else throw new TypeError("ID must be a number!");
if (typeof name=="string") {
// noinspection JSUnresolvedVariable
this.name = name;
} else throw new TypeError("Name must be a string!");
if(typeof manufacturer=="string") {
// noinspection JSUnresolvedVariable
this.manufacturer = manufacturer;
} else throw new TypeError("Manufacturer must be a string!");
if (typeof description=="string") {
// noinspection JSUnresolvedVariable
this.description = description;
} else throw new TypeError("Description must be a string!");
if(typeof genres=="Object") {
// noinspection JSUnresolvedVariable
this.genres=genres;
} else new TypeError("Genres must be an Array of strings!");
if (typeof targetPrice=="number") {
// noinspection JSUnresolvedVariable
this.targetPrice = targetPrice;
} else new TypeError("Target price must be a number!");
this.accumulatedMoney=0;
}
get accumulatedMoney() {
return this._accumulatedMoney;
}
set accumulatedMoney(money) {
this._accumulatedMoney=money;
}
get id() {
return this._id;
}
get name() {
return this._name;
}
get manufacturer() {
return this._manufacturer;
}
get description() {
return this._description;
}
get genres() {
return this._genres;
}
get targetPrice() {
return this._targetPrice;
}
}
我用 //noinspection JSUnresolvedVariable
来抑制警告。但应该有比这更好的解决方案。
您似乎是将构造函数 上的值分配给 getter 而不是以下划线为前缀的支持字段。
constructor(id,name,manufacturer,description,genres,targetPrice){
if(new.target==BasePunchStarter){
throw new TypeError("BasePunchStarter class cannot be instantiated directly!");
}
if(typeof id =="number") {
// use the backing field instead.
this._id = id;
[..]
如果您还没有这样做,您应该在使用它们之前声明您的支持字段。
您的代码不是惯用的 JS。该语言是松散类型的,其理念基于 duck typing。您在构造函数中所做的事情很糟糕,应该避免。 Java脚本不是 Java。如果你想要强静态类型,请使用 Flow or TypeScript.
getter 和 setter 在 ES6 中很容易使用类,就像对象字面量中的 getter 和 setter 一样。
如果您想要只读属性,您可以使用 _
编码约定并简单地避免设置器。如果我们采用文档中的简单示例,我们将得到以下结果:
class Person {
constructor(firstname, lastname) {
this._firstname = firstname;
this._lastname = lastname;
}
get firstname() {
return this._firstname;
}
get lastname() {
return this._lastname;
}
}
let person = new Person('John', 'Doe');
console.log(person.firstname, person.lastname); // John Doe
// This is ignored
person.firstname = 'Foo';
person.lastname = 'Bar';
console.log(person.firstname, person.lastname); // John Doe
在Java脚本中,这个方案就好了。但是,如果出于某种原因,您真的想要真正的封装,那么这不是可行的方法。事实上,仍然可以直接访问带有 _
前缀的内部属性:
class Person {
constructor(firstname, lastname) {
this._firstname = firstname;
this._lastname = lastname;
}
get firstname() {
return this._firstname;
}
get lastname() {
return this._lastname;
}
}
let person = new Person('John', 'Doe');
console.log(person.firstname, person.lastname); // John Doe
// This is NOT ignored
person._firstname = 'Foo';
person._lastname = 'Bar';
console.log(person.firstname, person.lastname); // Foo Bar
完全封装的最佳解决方案是使用 IIFE 创建本地作用域,并在实例上 Object.freeze()
防止不必要的更改。
使用吸气剂,它有效:
let Person = (() => {
let firstname,
lastname;
class Person {
constructor(first, last) {
firstname = first;
lastname = last;
}
get firstname() {
return firstname;
}
get lastname() {
return lastname;
}
}
return Person;
})();
let person = new Person('John', 'Doe');
Object.freeze(person);
console.log(person.firstname, person.lastname); // John Doe
// This is ignored
person.firstname = 'Foo';
person.lastname = 'Bar';
console.log(person.firstname, person.lastname); // John Doe
没有吸气剂,它不起作用:
let Person = (() => {
let firstname,
lastname;
class Person {
constructor(first, last) {
firstname = first;
lastname = last;
}
}
return Person;
})();
let person = new Person('John', 'Doe');
Object.freeze(person);
console.log(person.firstname, person.lastname); // undefined undefined
// This is ignored
person.firstname = 'Foo';
person.lastname = 'Bar';
console.log(person.firstname, person.lastname); // undefined undefined
请问,在ES6中,如何只使用getter而没有setter(readOnly)属性?为什么 Webstorm 告诉我这是一个错误?
这是我的代码:
class BasePunchStarter {
constructor(id,name,manufacturer,description,genres,targetPrice) {
if (new.target==BasePunchStarter) {
throw new TypeError("BasePunchStarter class cannot be instantiated directly!");
}
if (typeof id =="number") {
// noinspection JSUnresolvedVariable
this.id = id;
} else throw new TypeError("ID must be a number!");
if (typeof name=="string") {
// noinspection JSUnresolvedVariable
this.name = name;
} else throw new TypeError("Name must be a string!");
if(typeof manufacturer=="string") {
// noinspection JSUnresolvedVariable
this.manufacturer = manufacturer;
} else throw new TypeError("Manufacturer must be a string!");
if (typeof description=="string") {
// noinspection JSUnresolvedVariable
this.description = description;
} else throw new TypeError("Description must be a string!");
if(typeof genres=="Object") {
// noinspection JSUnresolvedVariable
this.genres=genres;
} else new TypeError("Genres must be an Array of strings!");
if (typeof targetPrice=="number") {
// noinspection JSUnresolvedVariable
this.targetPrice = targetPrice;
} else new TypeError("Target price must be a number!");
this.accumulatedMoney=0;
}
get accumulatedMoney() {
return this._accumulatedMoney;
}
set accumulatedMoney(money) {
this._accumulatedMoney=money;
}
get id() {
return this._id;
}
get name() {
return this._name;
}
get manufacturer() {
return this._manufacturer;
}
get description() {
return this._description;
}
get genres() {
return this._genres;
}
get targetPrice() {
return this._targetPrice;
}
}
我用 //noinspection JSUnresolvedVariable
来抑制警告。但应该有比这更好的解决方案。
您似乎是将构造函数 上的值分配给 getter 而不是以下划线为前缀的支持字段。
constructor(id,name,manufacturer,description,genres,targetPrice){
if(new.target==BasePunchStarter){
throw new TypeError("BasePunchStarter class cannot be instantiated directly!");
}
if(typeof id =="number") {
// use the backing field instead.
this._id = id;
[..]
如果您还没有这样做,您应该在使用它们之前声明您的支持字段。
您的代码不是惯用的 JS。该语言是松散类型的,其理念基于 duck typing。您在构造函数中所做的事情很糟糕,应该避免。 Java脚本不是 Java。如果你想要强静态类型,请使用 Flow or TypeScript.
getter 和 setter 在 ES6 中很容易使用类,就像对象字面量中的 getter 和 setter 一样。
如果您想要只读属性,您可以使用 _
编码约定并简单地避免设置器。如果我们采用文档中的简单示例,我们将得到以下结果:
class Person {
constructor(firstname, lastname) {
this._firstname = firstname;
this._lastname = lastname;
}
get firstname() {
return this._firstname;
}
get lastname() {
return this._lastname;
}
}
let person = new Person('John', 'Doe');
console.log(person.firstname, person.lastname); // John Doe
// This is ignored
person.firstname = 'Foo';
person.lastname = 'Bar';
console.log(person.firstname, person.lastname); // John Doe
在Java脚本中,这个方案就好了。但是,如果出于某种原因,您真的想要真正的封装,那么这不是可行的方法。事实上,仍然可以直接访问带有 _
前缀的内部属性:
class Person {
constructor(firstname, lastname) {
this._firstname = firstname;
this._lastname = lastname;
}
get firstname() {
return this._firstname;
}
get lastname() {
return this._lastname;
}
}
let person = new Person('John', 'Doe');
console.log(person.firstname, person.lastname); // John Doe
// This is NOT ignored
person._firstname = 'Foo';
person._lastname = 'Bar';
console.log(person.firstname, person.lastname); // Foo Bar
完全封装的最佳解决方案是使用 IIFE 创建本地作用域,并在实例上 Object.freeze()
防止不必要的更改。
使用吸气剂,它有效:
let Person = (() => {
let firstname,
lastname;
class Person {
constructor(first, last) {
firstname = first;
lastname = last;
}
get firstname() {
return firstname;
}
get lastname() {
return lastname;
}
}
return Person;
})();
let person = new Person('John', 'Doe');
Object.freeze(person);
console.log(person.firstname, person.lastname); // John Doe
// This is ignored
person.firstname = 'Foo';
person.lastname = 'Bar';
console.log(person.firstname, person.lastname); // John Doe
没有吸气剂,它不起作用:
let Person = (() => {
let firstname,
lastname;
class Person {
constructor(first, last) {
firstname = first;
lastname = last;
}
}
return Person;
})();
let person = new Person('John', 'Doe');
Object.freeze(person);
console.log(person.firstname, person.lastname); // undefined undefined
// This is ignored
person.firstname = 'Foo';
person.lastname = 'Bar';
console.log(person.firstname, person.lastname); // undefined undefined