es6 javascript的class类的new的新特性

new是从构造函数生成实例的命令。 ES6 为new命令引入了一个new.target属性,( 在构造函数中) 返回new命令作用于的那个构造函数。 如果构造函数不是通过new命令调用的, new.target会返回undefined, 因此这个属性可以用来确定构造函数是怎么调用的。

[javascript]  view plain  copy
  1. function Person(name) {  
  2.     if(new.target !== undefined) {  
  3.         this.name = name;  
  4.     } else {  
  5.         throw new Error(' 必须使用 new 生成实例 ');  
  6.     }  
  7. }  
  8. //  另一种写法  
  9. function Person(name) {  
  10.     if(new.target === Person) {  
  11.         this.name = name;  
  12.     } else {  
  13.         throw new Error(' 必须使用 new 生成实例 ');  
  14.     }  
  15. }  
  16. var person = new Person(' 张三 '); //  正确  
  17. var notAPerson = Person.call(person, ' 张三 '); //  报错  
上面代码确保构造函数只能通过new命令调用。
Class 内部调用new.target, 返回当前 Class。

[javascript]  view plain  copy
  1. class Rectangle {  
  2.     constructor(length, width) {  
  3.         console.log(new.target === Rectangle);  
  4.         this.length = length;  
  5.         this.width = width;  
  6.     }  
  7. }  
  8. var obj = new Rectangle(3, 4); //  输出 true  
需要注意的是, 子类继承父类时, new.target会返回子类。

[javascript]  view plain  copy
  1. class Rectangle {  
  2.     constructor(length, width) {  
  3.         console.log(new.target === Rectangle);  
  4.         // ...  
  5.     }  
  6. }  
  7. class Square extends Rectangle {  
  8.     constructor(length) {  
  9.         super(length, length);  
  10.     }  
  11. }  
  12. var obj = new Square(3); //  输出 false  
上面代码中, new.target会返回子类。
利用这个特点, 可以写出不能独立使用、 必须继承后才能使用的类。

[javascript]  view plain  copy
  1. class Shape {  
  2.     constructor() {  
  3.         if(new.target === Shape) {  
  4.             throw new Error(' 本类不能实例化 ');  
  5.         }  
  6.     }  
  7. }  
  8. class Rectangle extends Shape {  
  9.     constructor(length, width) {  
  10.         super();  
  11.         // ...  
  12.     }  
  13. }  
  14. var x = new Shape(); //  报错  
  15. var y = new Rectangle(3, 4); //  正确  
上面代码中, Shape类不能被实例化, 只能用于继承。
注意, 在函数外部, 使用new.target会报错。


Mixin 模式的实现

Mixin 模式指的是, 将多个类的接口“ 混入”( mixin)另一个类。 它在 ES6 的实现如下。

[javascript]  view plain  copy
  1. function mix(...mixins) {  
  2.     class Mix {}  
  3.     for(let mixin of mixins) {  
  4.         copyProperties(Mix, mixin);  
  5.         copyProperties(Mix.prototype, mixin.prototype);  
  6.     }  
  7.     return Mix;  
  8. }  
  9.   
  10. function copyProperties(target, source) {  
  11.     for(let key of Reflect.ownKeys(source)) {  
  12.         if(key !== "constructor" &&  
  13.             key !== "prototype" &&  
  14.             key !== "name"  
  15.         ) {  
  16.             let desc = Object.getOwnPropertyDescriptor(source, key);  
  17.             Object.defineProperty(target, key, desc);  
  18.         }  
  19.     }  
  20. }  
上面代码的mix函数, 可以将多个对象合成为一个类。 使用的时候, 只要继承这个类即可。

[javascript]  view plain  copy
  1. lass DistributedEdit extends mix(Loggable, Serializable) {  
  2.     // ...  
  3. }  


猜你喜欢

转载自blog.csdn.net/nimeghbia/article/details/80734255