在 ES12 中,新增了一个名为 new.target 的方法,它可以优化函数的调用方式,并避免一些 “坏味道”。在本篇文章中,我们来探索一下这个新方法。
概述
new.target 是一个内置变量,它可以在一个函数中通过 this 来访问。当使用 new 关键字调用一个函数时,new.target 会指向调用时的构造函数。如果该函数不是通过 new 关键字调用的,则 new.target 为 undefined。
因此,我们可以通过 new.target 来判断一个函数是如何被调用的。这对于函数的优化和避免 “坏味道” 非常有用。
优化函数调用
在ES以前的版本中,为了让一个函数能够作为构造函数来使用,我们通常会使用以下的写法:
function Person(name) { this.name = name; } var p = new Person('Tom');
这段代码可以创建一个名为 Person 的构造函数,并使用 new 关键字来创建一个名为 p 的对象。
但是这样会导致一些问题。如果在 Person 函数中使用了 this 关键字,但是忘记使用 new 关键字调用这个函数,那么 this 就会指向全局对象,从而引发一些问题。
为了避免这种情况,我们可以在 Person 函数的开头添加一个判断:
-- -------------------- ---- ------- -------- ------------ - -- ------- ---------- -------- - ------ --- ------------- - --------- - ----- - --- - - --------------
这样,即使忘记使用 new 关键字调用 Person 函数,也会自动将其转换为构造函数的方式。但是这样写法比较繁琐,而且需要写重复的代码。
在 ES12 中,我们可以使用 new.target 方法来优化这个写法:
-- -------------------- ---- ------- -------- ------------ - -- ------------- - ------ --- ------------- - --------- - ----- - --- - - --------------
这样我们就可以避免在函数体内使用 this 时出现的坏味道了。
避免 "坏味道"
在编写 JavaScript 代码时,我们经常会遇到一些 “坏味道” (Bad Smell),即代码的可读性和可维护性差,容易出现各种错误和问题。一些常见的坏味道包括:
- 暴露全局变量
- 没有使用局部变量声明
- 没有使用 const 或 let 声明变量
- 没有使用严格模式
- 等等
使用 new.target 可以避免一些坏味道的情况。例如,在 ES5 中,经常会出现类似的写法:
-- -------------------- ---- ------- -------- ------------ - --------- - ----- -------- --------- - ------------------ - - --- - - --- --------------
在这个例子中,getName 函数使用了外部的变量 name,但是在函数内部没有对它进行声明。这会在严格模式下报错,而且也不利于代码的维护。
在 ES6 中,我们可以使用 let 或 const 关键字声明变量,避免这个问题。但是使用 new.target 可以更好地避免这个坏味道:
-- -------------------- ---- ------- -------- ------------ - -- ------------- - ----- --- ------------- ---- -- ------ ---- ------ - --- ----- - ----- -------- --------- - ------------------- - ------------ - -------- - --- - - --- -------------- ------------ -- -- ----- --- - - ----------------- -------- ---- -- --------- ---- -- ------ ---- ---
在这个例子中,我们通过使用 new.target 来确保 Person 函数只能通过 new 关键字来调用。同时,我们使用了 let 来声明了一个局部变量 _name,避免了 getName 函数中使用未声明的变量的问题。
总结
在 ES12 中,new.target 是一个非常有用的方法,可以优化函数的调用方式,并且避免一些坏味道的情况。它的用法是通过判断 new.target 是否为 undefined 来实现。如果 new.target 为 undefined,则说明该函数不是通过 new 关键字调用的。
使用 new.target 可以避免一些常见的 “坏味道”,例如未声明变量、在函数内部使用 this 等问题。同时,它还可以优化函数的调用方式,使得函数更加易于维护和调用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e3396af6b2d6eab3ea1c13