从零开始学_JavaScript_系列(63)——class(4)静态方法和new.target
来源:互联网 发布:linux解压tar包 编辑:程序博客网 时间:2024/06/06 01:15
9、类静态方法
9.1、基本概念
所谓静态方法,在class指专属于class本身的方法,而且不会被类的实例所继承。
如代码:
class Foo { static test() { console.log("this is static") }}Foo.test() // this is staticlet p = new Foo()p.test() // Uncaught TypeError: p.test is not a function
至于实现原理,很简单。只有构造函数原型链上(prototype属性)的方法才会被构造函数的实例所继承。
因此,把静态方法直接挂载在类本身上,而不是类的原型链上,即可以。
如何证明这一点呢?普通方法是不行的,原因在于通过类声明的方法,他的enumberable的属性是false,因此是不可以枚举的。
例如Object.keys(Foo)
之类的方法是不可行的
有两个办法:
- 通过
console.dir(Foo)
来查看整个Foo类的原型链; - 通过
Object.getOwnPropertyNames(Foo)
或Reflect.ownKeys(Foo)
来查看Foo上面有哪些属性,这两个方法可以查看enumberable值为false的属性。参照博客对象的扩展(3)当枚举、原型链遇见对属性的操作
Object.getOwnPropertyNames(Foo) // ["length", "prototype", "test", "name"]Reflect.ownKeys(Foo) // ["length", "prototype", "test", "name"]
9.2、this
静态方法的this指向谁呢?
我们知道,对象的方法中的this,指向对象自己。
而类是对象,类的静态方法就是对象的方法,因此,类的静态方法里的this也指向类本身。
class Foo { static test() { return this }}Foo.test() === Foo // true
9.3、继承的静态方法
目前还没涉及到类的继承,但可以给出一个结论:
- 类的静态方法可以被继承;
- 父类的静态方法被继承后,this指向子类;
另外提一句,类的继承,是让子类的__proto__
属性指向父类。
9.4、类没有静态属性
至少目前没有。
当然,可以在类的constructor方法里,通过this.xx设置类的静态属性,但不能直接通过static xx
这样的方式来定义静态属性。
10、new.target
10.1、基本概念
简单来说,这个属性用于表示当函数通过new来调用时(即函数被当做构造函数),new命令作用的那个构造函数是谁。
他有以下几个规律:
1、被用在函数内部,函数外部直接调用会报错;
new.target; // Uncaught SyntaxError: new.target expression is not allowed here
2、当函数被作为构造函数new时,new.target指向构造函数;
function Test() { return new.target}new Test() === Test; // true
3、当new.target处于类的constructor属性中时,指向类本身
class Foo { constructor() { return new.target }}new Foo() === Foo; // true
4、当父类被子类继承时,父类中的constructor的new.target指向子类(而非父类)。
MDN的介绍
这个比较特殊,在es5中似乎实现起来很复杂
class Foo { constructor() { console.log(new.target === Bar) }}class Bar extends Foo { constructor() { super() // 这个表示是父类的构造函数 console.log(new.target === Bar) }}new Bar()// true// true
5、当函数并没有被new所调用时,而是普通调用,那么new.target的值是undefined
function Test() { return new.target}Test() // undefined
10.2、应用
由于这个特点,因此在父类的constructor函数内,可以通过new.target是否等于父类,来限制允对父类的使用。
例如:
1、如果只允许在等于父类的情况下执行,否则报错,那么该父类是无法被继承的;
2、如果只允许在不等于父类的情况下执行,否则报错,那么该父类是无法被单独使用的,必须被继承后才能使用。
- 从零开始学_JavaScript_系列(63)——class(4)静态方法和new.target
- 从零开始学_JavaScript_系列(61)——class(2)私有方法、this
- 从零开始学_JavaScript_系列(62)——class(3)setter和getter、Generator、async函数
- 从零开始学_JavaScript_系列(64)——class的继承(1)基本概念、继承构造函数和class
- 从零开始学_JavaScript_系列(51)——Promise(4)Promise.resolve和Promise.reject
- 从零开始学_JavaScript_系列(60)——class(1)基本概念
- 从零开始学_JavaScript_系列(30)——NodeList
- 从零开始学_JavaScript_系列(32)——事件广播
- 从零开始学_JavaScript_系列(43)——Symbol简述
- 从零开始学_JavaScript_系列(47)——Reflect
- 从零开始学_JavaScript_系列(58)——Thunk函数
- 从零开始学_JavaScript_系列(59)——async函数
- 从零开始学_JavaScript_系列(26)——dojo的aspect方法
- 从零开始学_JavaScript_系列(28)——dojo的aspect.around方法
- 从零开始学_JavaScript_系列(29)——apply和call
- 从零开始学_JavaScript_系列(44)——ES6新增数据结构:Set类型和WeakSet
- 从零开始学_JavaScript_系列(45)——ES6新增数据结构:Map和WeakMap
- 从零开始学_JavaScript_系列(53)——Generator函数(1)基本概念和示例
- 流光特效
- Ubuntu 安装网易云音乐
- MySQL多表连接分组(Group by)后的统计
- Ubuntu14.04下telnet的使用
- arcgis api JavaScript打印地图图例显示不正确
- 从零开始学_JavaScript_系列(63)——class(4)静态方法和new.target
- 设计模式之工厂方法模式
- mysql中char与varchar的区别分析
- YYWebImage使用
- Junit单元测试学习笔记三
- 485. Max Consecutive Ones
- oracle使用笔记
- 关于frameworks层源码编译
- Nio(九)ServerSocketChannel