HuangHongRui / Notebook

:pencil2: Yeah.. This's My NoteBook...:closed_book:
0 stars 0 forks source link

Es6_Javascript中的类 [在类的构造函数中使用new.target] #28

Open HuangHongRui opened 7 years ago

HuangHongRui commented 7 years ago

在类的构造函数中也可以通过 new.target 来确定类是如何被调用的。 简单情况下,new.target 等于类的构造函数

Code:

class Rectangle {
constructor (length, width) {
console.log(new.target === Rectangle);
this.length = length;
this.width = width;
}
}
var obj = new Rectangle(3,4)

当调用了 new Rectangle(3,4) 时等价于 Rectangle 的 new.target类构造函数必须通过 new 关键字调用 所以总是在类的构造函数中定义 new.target 属性。

HuangHongRui commented 7 years ago

但有时,其值也会不同。

class Rectangle {
  constructor (length, width) {
    console.log(new.target === Rectangle);
    this.length = length;
    this.width = width;
  }
}
class Square extends Rectangle {
  constructor (length) {
    super(length,length)
  }
}

var obj = new Square(3)  //  false

new.target 的值是 Square 因Square 调用了 Rectangle 的构造函数, So当调用发生时 new.target 等于 Square [重点] 因每个构造函数都可以根据自身被调用的方式改变自己的行为。

例如: 可以用new.target 创建一个抽象基类 [不能被直接实例化的类]

//抽象基类
class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error ('这个类不可被实例化')
    }
  }
}

class Rectangle extends Shape {
  constructor (length , width) {
    super()
    this.length = length
    this.width = width
  }
}

let r = new Shape  //  因实例化抛错
let y = new Rectangle(3,4)
console.log(y instanceof Shape)  //  true

每当 new.target是shape时构造函数总抛出错误,相当于 调用了 new Shape() 但,仍可用 Shape 作为基类派生其他类 Code中,Rectangle便是如此。 super()调用执行了 Shape 的构造函数, new.targetRectangle等价,所以构造函数继续执行不会抛错。