字段
类字段直接在类的正文中声明,而不是显式地作为 this
值的属性添加。但是,结果是相同的:在类的实例上定义的属性。
class MyClass {
myField;
}
const myClassInstance = new MyClass();
myClassInstance;
> MyClass { myField: undefined }
您可以初始化具有值的字段。这通常是一个默认值,类中的逻辑可以覆盖该值
class MyClass {
myResult = false;
set setValue( myValue ) {
this.myResult = myValue;
}
}
const myClassInstance = new MyClass();
myClassInstance;
> Object { myResult: false }
myClassInstance.setValue = true;
myClassInstance;\
> Object { myResult: true }
类字段在功能上与使用 this
附加到类的属性相同。这意味着可以像任何其他属性一样从类外部访问和修改它们。
class MyClass {
myField = true;
}
const myClassInstance = new MyClass();
myClassInstance.myField;
> true
myClassInstance.myField = false;
myClassInstance.myField;
> false;
字段为类的某些更高级功能提供了基础。
私有字段和方法
私有字段和方法在类外部不可访问。私有属性与类的实例关联,这意味着每个实例都包含其自己的一组私有字段和方法,如类上定义的那样。
要使属性成为私有属性,请在声明标识符时在标识符的开头添加 #
class MyClass {
#myPrivateField = true;
#myPrivateMethod() {}
}
const myClassInstance = new MyClass();
myClassInstance;
> MyClass { #myPrivateField: true }
#myPrivateField: true
<prototype>: Object { … }
constructor: class MyClass {}
<prototype>: Object { … }
必须在包含类的正文中声明私有字段。您可以在以后将其值更改为 this
的属性,但不能使用 this
创建该字段。
私有字段无法从脚本的其他位置访问。这可以防止数据属性在提供的 getter 和 setter 方法之外被更改以与它们包含的值进行交互,并且可以防止直接访问仅供类本身内部使用的方法。
class MyClass {
#myResult = false;
set setValue( myValue ) {
this.#myResult = myValue;
}
}
const myClassInstance = new MyClass();
myClassInstance;
> MyClass { #myResult: false }
myClassInstance.#myResult = true;
> Uncaught SyntaxError: reference to undeclared private field or method #myResult
myClassInstance.setValue = true;
myClassInstance;\
> MyClass { #myResult: true }
但是,请记住,浏览器开发人员控制台通常在允许访问私有字段以进行调试方面 非常宽松,尽管不一致
class MyClass {
#myPrivateField = true;
#myPrivateMethod() {
console.log( "This is inside a private method." );
}
}
const myClassInstance = new MyClass();
myClassInstance;
> MyClass {#myPrivateField: true}
myClassInstance.#myPrivateField;
> true
myClassInstance.#myPrivateMethod();
> "This is inside a private method."
class MyClass {
#myPrivateField = true;
#myPrivateMethod() {
console.log( "This is inside a private method." );
}
}
const myClassInstance = new MyClass();
myClassInstance;
> MyClass {#myPrivateField: true}
myClassInstance.#myPrivateField;
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField
myClassInstance.#myPrivateMethod();
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateMethod
私有字段的范围严格限制在包含它们的类的正文中,这意味着即使子类也无法访问与父类关联的私有字段
class MyClass {
#myPrivateField = true;
}
class ChildClass extends MyClass {
childMethod() {
console.log( this.#myPrivateField );
}
}
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField
静态字段和方法
静态字段和方法是类本身的成员,而不是该类的实例的成员。因此,静态字段为数据提供了一个中心点,该数据对于类的每个实例不是唯一的,但这些实例可能需要引用——例如,共享配置信息。静态方法通常是用于处理类实例的实用程序函数,例如比较实例或根据它们包含的字段对实例进行排序。
要在类的正文中定义静态字段和方法,请使用 static
关键字
class MyClass {
static myStaticField;
static myStaticMethod() {}
}
const myClassInstance = new MyClass();
您还可以使用点表示法创建静态方法
class MyClass {
constructor() {}
}
MyClass.myStaticMethod = function() {}
您无法从其类的实例访问静态属性,但它们在类构造函数上可用
class MyClass {
static myStaticField = true;
static myStaticMethod() {
console.log( "A static method." );
}
}
const myClassInstance = new MyClass();
myClassInstance.myStaticField;
> undefined
myClassInstance.myStaticMethod();
> Uncaught TypeError: myClassInstance.myStaticMethod is not a function
MyClass.myStaticField;
> true
MyClass.myStaticMethod();
> "A static method."
它们在技术上不是必需的,但使用静态方法是创建实用程序以处理类实例的最佳实践。这方面的示例可能包括专用于对类实例进行排序的静态方法,或包含创建类实例所需的任何设置然后返回类实例的静态工厂方法
class User {
constructor( name, email ) {
this.name = name;
this.email = email;
}
static fromObject( myObject ) {
return new User( myObject.name, myObject.email ?? "Omitted" );
}
}
const userObject = {
"name" : "My Name",
"email" : "my@email.address"
};
const secondUserObject = {
"name" : "My Name"
};
const firstUser = User.fromObject( userObject );
const secondUser = User.fromObject( secondUserObject );
firstUser;
> Object { name: "My Name", email: "my@email.address" }
secondUser;
> Object { name: "My Name", email: "Omitted" }
检查您的理解
以下哪种类型的字段只能从类内部访问?
静态字段