1、什么叫做静态方法?
1.1、类相当于实例的原型, 所有在类中定义的方法, 都会被实例继承。如果在一个方法前,加上Static关键字,就表示该方法不会被继承,而是直接通过类来调用,这被称为 “静态方法”。
1.2、我们可以从代码上进行更深的理解。
下面的代码中,Sea类的classMethod方法前有static关键字,表明该方法是一个静态方法,可以直接在Sea类上调用(Sea.classMethod()),而不是在Sea类的实例上调用静态方法,会抛出一个错误,表示不存在该方法。
父类的静态方法可以被子类继承。
1 class Sea { 2 static classMethod(){ 3 return 'hello' 4 } 5 } 6 Sea.classMethod() //'hello' 7 var foo =new Foo(); 8 foo.classMethod() 9 // TypeError: foo.classMethod is not a function
下面代码中。父类Sea有一个静态方法,子类Ocean可以调用这个方法。
静态方法也是可以从super对象上调用。
1 class Sea{ 2 static classMethod(){ 3 return 'hello' 4 } 5 } 6 class Ocean extends Sea{} 7 Ocean.clsaaMethod(); //'hello'
1.3、下面就是整个静态方法的使用(完整的可以直接用)
1 class Sea{ 2 static classMethod(){ 3 return 'hello' 4 } 5 } 6 class Ocean extends Sea{ 7 static classMethod(){ 8 return super.clsassMethod()+',too' 9 } 10 } 11 Ocean.classMethod();
2、什么叫静态属性?
2.1、静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。
2.2、我们可以从代码上进行更深的理解。
下面的写法为Sea定义了一个静态prop,目前,只有这种写法可行,因为ES6明确规定,Class内部只有静态方法,没有静态属性。
1 class Foo {} 2 Foo.prop = 1; 3 Foo.prop // 1
2.3、ES7 有一个静态属性的提案, 目前 Babel 转码器支持。这个提案对实例属性和静态属性, 都规定了新的写法。
2.3.1、 类的实例属性
类的实例属性可以用等式, 写入类的定义之中。
1 // 以下两种写法都无效 2 class Sea { 3 // 写法一 4 prop: 2 5 // 写法二 6 static prop: 2 7 } 8 Sea.prop // undefined
2.4、下面代码中,myProp就是MyClass的实例属性。在MyClass的实例上,可以读取这个属性。以前,我们定义实例属性,只能写在类的从structor方法里面。
1 calss MyClass{ 2 myProp=42; 3 constructor(){ 4 console.log(this.myProp); 5 } 6 }
2.5、下面代码中,构造方法constructor里面,定义了this.state属性。有了新的写法以后,可以不在constructor方法里面定义。
1 class ReactCounter extends React.Component { 2 constructor(props) { 3 super(props); 4 this.state = { 5 count: 0 6 }; 7 } 8 }
这种写法比以前更清晰。
为了可读性的目的, 对于那些在constructor里面已经定义的实例属性, 新写法允许直接列出。
1 class ReactCounter extends React.Component { 2 state = { 3 count: 0 4 }; 5 }
2.6、下面即使整个静态属性的使用(完整的可以直接用)
1 class ReactCounter extends React.Component { 2 constructor(props) { 3 super(props); 4 this.state = { 5 count: 0 6 }; 7 } 8 state; 9 }
3、类的静态属性
3.1、类的静态属性只要在上面的实例属性写在前面, 加上static关键字就可以了。
1 class MyClass { 2 static myStaticProp = 42; 3 constructor() { 4 console.log(MyClass.myProp); // 42 5 } 6 }
同样的,这个写法大大方便了静态属性的表达。
1 // 老写法 2 class Foo {} 3 Foo.prop = 1; 4 // 新写法 5 class Foo { 6 static prop = 1; 7 }
上面代码中, 老写法的静态属性定义在类的外部。 整个类生成以后, 再生成静态属性。 这样让人很容易忽略这个静态属性, 也不符合相关代码应该放在一起的代码组织原则。 另外, 新写法是显式声明( declarative), 而不是赋值处理, 语义更好。