ES12 中 JavaScript 类的实例化方式
JavaScript 类是面向对象编程中的重要概念,它允许我们以一种优雅而直观的方式组织代码。ES6 中引入了类的概念,而 ES12 中进一步完善了类的实例化方式。本文将详细介绍 ES12 中 JavaScript 类的实例化方式,包括 new.target 和标准的 extends。
new.target
首先,我们先来介绍一下 ES12 中引入的新特性 new.target。new.target 是一个元属性,它可以在类或函数内部使用,用来确定函数或类是通过 new 表达式被调用还是通过普通的函数调用被调用。
class Person { constructor() { console.log(new.target === Person); } } const person = new Person(); // 输出 true Person.call(person); // 输出 false
在上面的代码中,当我们使用 new 表达式创建 Person 类的实例时,new.target 等于 Person,因此会输出 true。而当我们使用 Person.call 来调用类的构造函数时,new.target 指向的是构造函数的父类,因此输出 false。
new.target 在开发中的应用场景很广,例如我们可以根据 new.target 的值来改变实例化对象的行为。下面是一个例子:
// javascriptcn.com 代码示例 class Animal { constructor() { if (new.target === Animal) { throw new Error('Animal 类不能直接实例化'); } } } class Dog extends Animal {} const animal = new Animal(); // 报错:Animal 类不能直接实例化 const dog = new Dog(); // 正常实例化
在上面的代码中,当我们使用 new 表达式创建 Animal 类的实例时,由于 new.target 等于 Animal,所以会抛出错误提示 Animal 类不能直接实例化。而当我们使用 new 表达式创建 Dog 类的实例时,new.target 等于 Dog,不会产生任何错误。
extends
ES6 中引入了 extends 关键字,用来实现类继承。而 ES12 中,extends 进一步支持类的实例化。
// javascriptcn.com 代码示例 class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { constructor(name) { super(name); } bark() { console.log(`${this.name} 汪汪叫`); } } const dog = new Dog('小宝'); dog.bark(); // 输出 "小宝 汪汪叫"
在上面的代码中,我们定义了一个 Animal 类和一个 Dog 类,Dog 类继承了 Animal 类,并添加了一个 bark 方法。在实例化 Dog 类时,我们使用了 new 关键字来创建实例对象,并向构造函数传递了一个参数,这样构造函数就能在实例初始化过程中为 Dog 对象设置一个初始的属性 name。
通过 extends 和 super,我们可以实现类的继承,而且在 ES12 中,我们还可以使用继承的方式来实现类的实例化。
// javascriptcn.com 代码示例 class Animal { constructor(name) { this.name = name; } static create(name) { return new this(name); } } class Dog extends Animal { bark() { console.log(`${this.name} 汪汪叫`); } } const dog = Animal.create('小宝'); dog.bark(); // 输出 "小宝 汪汪叫"
在上面的代码中,我们在 Animal 类上定义了一个静态方法 create,这个方法会使用 new 关键字来创建一个新的实例。在 Dog 类中,我们通过继承 Animal 类来获得 create 方法,然后使用 Animal.create 方法来创建 Dog 类的实例。
这种方式的好处在于,我们可以利用继承机制来避免在每个类中都定义一个 create 方法,从而提高代码的复用性和可读性。
总结
ES12 中增强了 JavaScript 类的实例化方式,我们可以使用 new.target 来判断类是通过 new 表达式被调用还是通过普通的函数调用被调用。同时,我们还可以使用 extends 关键字来实现类的继承和实例化。
类是面向对象编程中不可或缺的一部分,深入学习类的实例化方式能够让我们更好地组织代码、提高代码复用性和可维护性。最后,附上一份完整的示例代码,希望对大家有所帮助。
// javascriptcn.com 代码示例 class Person { constructor() { console.log(new.target === Person); } } const person = new Person(); // 输出 true Person.call(person); // 输出 false class Animal { constructor(name) { this.name = name; } static create(name) { return new this(name); } } class Dog extends Animal { bark() { console.log(`${this.name} 汪汪叫`); } } const dog = Animal.create('小宝'); dog.bark(); // 输出 "小宝 汪汪叫"
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6583838bd2f5e1655de65492