2021.05.25(静态方法、静态属性)
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加
上 static 关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
1. class Foo { 2. static classMethod() { 3. return 'hello'; 4. } 5. } 6. 7. Foo.classMethod() // 'hello' 8. 9. var foo = new Foo(); 10. foo.classMethod() 11. // TypeError: foo.classMethod is not a function
上面代码中, Foo 类的 classMethod 方法前有 static 关键字,表明该方法是一个静态方法,
可以直接在 Foo 类上调用( Foo.classMethod() ),而不是在 Foo 类的实例上调用。如果在实
例上调用静态方法,会抛出一个错误,表示不存在该方法。
注意,如果静态方法包含 this 关键字,这个 this 指的是类,而不是实例。
1. class Foo { 2. static bar() { 3. this.baz(); 4. } 5. static baz() { 6. console.log('hello'); 7. } 8. baz() { 9. console.log('world'); 10. } 11. } 12. 13. Foo.bar() // hello
上面代码中,静态方法 bar 调用了 this.baz ,这里的 this 指的是 Foo 类,而不
是 Foo 的实例,等同于调用 Foo.baz 。另外,从这个例子还可以看出,静态方法可以与非静态方
法重名。
父类的静态方法,可以被子类继承。
1. class Foo { 2. static classMethod() { 3. return 'hello'; 4. } 5. } 6. 7. class Bar extends Foo { 8. } 9. 10. Bar.classMethod() // 'hello'
上面代码中,父类 Foo 有一个静态方法,子类 Bar 可以调用这个方法。
静态方法也是可以从 super 对象上调用的。
1. class Foo { 2. static classMethod() { 3. return 'hello'; 4. } 5. } 6. 7. class Bar extends Foo { 8. static classMethod() { 9. return super.classMethod() + ', too'; 10. } 11. } 12. 13. Bar.classMethod() // "hello, too"
静态属性
静态属性指的是 Class 本身的属性,即 Class.propName ,而不是定义在实例对象( this )上的属性。
1. class Foo { 2. } 3. 4. Foo.prop = 1; 5. Foo.prop // 1
上面的写法为 Foo 类定义了一个静态属性 prop 。
目前,只有这种写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。现在有
一个提案提供了类的静态属性,写法是在实例属性的前面,加上 static 关键字。
1. class MyClass { 2. static myStaticProp = 42; 3. 4. constructor() { 5. console.log(MyClass.myStaticProp); // 42 6. } 7. }
这个新写法大大方便了静态属性的表达。
1. // 老写法 2. class Foo { 3. // ... 4. } 5. Foo.prop = 1; 6. 7. // 新写法 8. class Foo { 9. static prop = 1; 10. }
上面代码中,老写法的静态属性定义在类的外部。整个类生成以后,再生成静态属性。这样让人很容易
忽略这个静态属性,也不符合相关代码应该放在一起的代码组织原则。另外,新写法是显式声明
(declarative),而不是赋值处理,语义更好。
2021-05-25 17:12:48