在前端开发中,构造函数是非常常见的一种函数类型,用于创建实例对象。而在 ECMAScript 2020 中,新增了一个 new.target 属性,可以用来判断当前函数是否使用了 new 关键字调用,从而方便我们在构造函数中区分实例化过程与普通函数的调用过程,并做出相应的处理。
new.target 的基本用法
new.target 属性是 ECMAScript 2020 中新增的一个元属性,它用于返回当前函数是否被 new 关键字调用。如果是,则返回函数本身,否则返回 undefined。
下面是 new.target 的基本使用方法:
function Person() { console.log(new.target === Person); } Person(); // false new Person(); // true
在上面的例子中,我们定义了一个 Person 函数。当使用 new 关键字调用 Person 函数时,new.target 返回 Person 函数本身,因此上面的代码输出 true。而当直接调用 Person 函数时,new.target 返回 undefined,因此输出 false。
判断是否为构造函数
借助 new.target 属性,我们可以轻易地判断当前函数是否使用了 new 关键字调用,从而判断当前函数是否为构造函数。
下面是一个判断当前函数是否为构造函数的例子:
-- -------------------- ---- ------- -------- ------------ ---- - -- ------------------------ -- ------------- - ------ --- ------------ ----- - --------- - ----- -------- - ---- - ----- ------ - --- ------------- ---- ----- ------- - -------------- ---- ------------------ ---------- -------- -- ---- ------------------- ---------- -------- -- ----
在上述例子中,我们对 Person 函数做了一些修改,如果当前函数不是构造函数,则强制将其转化为构造函数并创建一个新的实例对象。这样一来,我们就可以在创建实例对象的同时,确保调用构造函数,并将相关参数正确地传递给构造函数。
使用场景举例
单例模式
在使用单例模式时,我们通常需要限制该类只能实例化一次,从而避免多次实例化导致的资源浪费等问题。而借助 new.target 属性,我们可以轻松地判断当前类是否已经实例化过了,如果是,则返回已有的实例对象;如果不是,则创建新实例对象并返回。下面是一个单例模式的例子:
-- -------------------- ---- ------- ----- --------- - ------------- - -- ----------- --- ------------------- - ------ ------------------- - --------- - ------------ ------------------ - ----- - - ----- -- - --- ------------ ----- -- - --- ------------ -------------- --- ---- -- ---- ----- -- - ------------ -------------- --- ---- -- ----
在上述例子中,我们通过判断 new.target 是否等于 Singleton.instance 来判断 Singleton 是否已经实例化过了。如果已经实例化,则返回已有的实例对象,否则创建新实例对象并返回。在这里,我们使用了静态属性 instance 来记录 Singleton 实例。
Mixin
Mixin 是一种将多个类的功能组合在一起的方法。借助 new.target 属性,我们可以轻松地实现 Mixin 功能,从而避免了多次继承的问题。下面是一个 Mixin 的例子:
-- -------------------- ---- ------- -------- ---------------- - ----- --- - -------------------- - --- ------ ----- -- ------- - ----- -------- - --- --------------- ------------------------------------------------- -- - ----- --- - ----------------------------------------- ------ --------------------------- ----- ----- --- - - - ------ ---- - ----- - - ----- - -------------- -- ---- - - ----- - - ----- - -------------- -- ---- - - ----- - ------- -------- -- - ------------- - -------- - - ----- - - --- ---- -------- -- - -- -
在上述例子中,我们通过 Mixin 函数将 A 类和 B 类的功能混合到 C 类中。在 Mixin 函数中,我们先将传递进来的多个类实例化,并将所有属性和方法复制到 Mix 类中,然后再让 C 类继承 Mix 类即可。在混合的过程中,我们借助了 new.target 属性来判断当前是否为构造函数,从而避免了多次实例化问题。
总结
ECMAScript 2020 的 new.target 属性为我们提供了一个非常方便的特性,可以用来判断当前函数是否使用了 new 关键字调用,从而方便我们在构造函数中区分实例化过程与普通函数的调用过程,并做出相应的处理。借助 new.target 属性,我们可以轻松地实现诸如单例模式、Mixin 等常见的设计模式,并大大提高开发效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6496bee948841e98943f816d