在ECMAScript 2015引入类(class)的语法之后,Javascript成为了一门更加现代化的面向对象编程语言。ECMAScript 2018引入了一个新的特性 —— new.target。本文将介绍new.target在类构造器中的应用,包含学习和指导意义(本篇文章假定读者已对ES6中class的基本语法和概念有了基本了解)。
1. new.target是什么?
在ES6之前,我们实例化对象时经常手动检查构造函数是否使用了new操作符,这样可以防止使用函数来当做构造函数或者当做工厂函数使用。看下面一段代码:
function Magic() { if (!(this instanceof Magic)) { throw new Error("Magic must be called with new"); } console.log("Magic!"); } var obj = Magic(); // throws "Must be called with new"
在ES6中,引入了new.target,使得检查是否使用new的操作更加便捷。new.target始终指向new操作符后面的构造函数或者类,如果函数不是通过new来实例化的,那么new.target值为undefined。看下面这段代码:
-- -------------------- ---- ------- ----- ----- - ------------- - ------------------------ - - ----- ---------- ------- ----- -- --- ----- - --- -------- -- ---- ----- --- ---------- - --- ------------- -- ---- ---------- --- ------ - -------- -- ---- ---------
2. new.target在类构造器中的应用
new.target有哪些在类的构造器中的应用呢?有一些常见的应用场景如下:
检查继承链中使用了new操作符
在开发过程中,我们经常使用继承来复用代码。当子类继承父类时,我们需要在子类构造函数中调用父类的构造函数。我们可以使用super关键字来调用父类构造器,但是我们也需要确定该构造器是通过new来初始化的。看下面这个例子:
-- -------------------- ---- ------- ----- ----- - ------------- - -- ----------- --- ------ - ----- --- ------------ ----------- -------- --------- - ---------------------- - - ----- ---------- ------- ----- -- --- ----- - --- -------- -- ------ ------ ----------- -------- ------- --- ---------- - --- ------------- -- ---- ----------
如上所述,我们可以使用new.target来检查继承链中是否使用了new操作符。如果new.target等于父类构造函数时,就抛出一个错误,这样可以让该类成为一个抽象类。
继承类的修改
当一个类继承另一个类的时候,子类可以继承父类的所有属性和方法。当我们需要修改父类的行为时,我们可以通过覆盖父类的方法来实现,但有时父类的构造函数也需要修改。通常,我们覆盖父类的方法来调用父类的构造函数。看下面这个例子:
-- -------------------- ---- ------- ----- ----- - ------------- - ------------------ --------------- - - ----- --- ------- ----- - ------------- - ---------------- --------------- -------- - - --- ------ -- ---- ---- ------------- - ------ -------------
但有时子类可能会覆盖的父类的构造函数,这时候我们就需要通过new.target来进行修改。看下面这个例子:
-- -------------------- ---- ------- ----- ----- - ------------- - ------------------ --------------- - ------ - --------------------- - - ----- --- ------- ----- - ------------- - ---------------- --------------- -- ----------- --- ---- - ----- --- ------------ ----------- -------- --------- - -------- - ------ - ------------------ -------- ------------- - - --- ------ -- ---- ---- ------------- - ------ ------------- --- --------------- -- ---- ------- --- ------------- -- ---- ------ ------ - -------
如上所述,我们可以在子类的构造函数中使用new.target来确保子类不会被调用。这有利于我们编写一些框架和代码库,可以设置代码的规范,让其他开发者遵循你所设定的规范,防止他们不正确地使用你的API。
3. 总结
本文介绍了ES2018新增的特性new.target在类构造器中的应用,包含检查继承链中是否使用了new操作符和继承类的修改这两个常见应用场景。在实现类的继承和封装时,new.target可以让我们实现更加高效和规范的代码。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64b34eb948841e9894f920a2