在以前的 ECMAScript 版本中,函数名属性表现得相当奇怪。您可能希望在调试或其他用例中访问函数的名称属性,但是在某些情况下,结果不仅令人困惑,而且还可能有误导性。 ES6 规范稍微改善了这一点,但是在 ES7 中,我们有了更好的方式来访问函数的名称。
函数的名称属性
首先,让我们回顾一下在旧版本的 JavaScript 中函数名属性到底是什么。实际上,"函数名属性"并不是一个真正的属性,因为它对于不同的函数类型有着不同的值。例如,对于匿名函数(通过函数表达式定义的函数),其名称属性值将是空字符串:
const anonymousFunc = function() {}; console.log(anonymousFunc.name); // 输出: ""
相反,如果将函数定义为具有名称,则名称属性将是该名称的字符串表示形式:
function namedFunc() {} console.log(namedFunc.name); // 输出: "namedFunc"
另外,如果将同一函数分配给多个变量,则它们都将具有相同的名称属性:
const func1 = function namedFunc() {}; const func2 = func1; console.log(func1.name); // 输出: "namedFunc" console.log(func2.name); // 输出: "namedFunc"
这看起来没有什么问题,但是如果在使用继承时出现问题。想象一下我们使用解构将基类的某个方法复制到子类中:
-- -------------------- ---- ------- ----- ----------- - ---------- -- - ----- -------------- ------- ----------- -- ----- - -------- - - --- -------------- --------------------------------- - --------- ------------------------------------------------- -- --- ---------- ---------------------------------------------------- -- --- --
这里我们希望 MyDerivedClass
的方法名称是 "myMethod",但实际上它是一个空字符串。新标准修复了这个问题。
ES7 中的修复
让我们看一下如何修复这个问题。ES7 引入了一个新特性,称为函数 toString()
方法的改进版 - Function.prototype.toString()
. 在 ES7 中,函数名称不再取决于函数声明方式而是始终正确地反映给定函数的名称。换句话说,使用继承、定义多个变量或者将函数作为参数传递时,都不会打乱名称属性。
-- -------------------- ---- ------- -------- ----------- -- ----- ---------- - ---------- ---------------------------------- -- --- --------- ----------- --- ----- ----------- - ---------- -- - ----- -------------- ------- ----------- -- ----- ------ - --- ----------------------- --------------------------------- - ------- ------------------------------------------------------- -- --- --------- ---------- --- ---------------------------------------------------------- -- --- --------- ---------- ---
这里我们使用类相同的方式在 MyDerivedClass
中引入了 myMethod
. 与上文不同的是,现在通过 toString()
方法输出时,属性名称均正确地显示为 "myMethod".
总结
ES7 引入的新特性解决了函数名属性的歧义问题。以前,这可能会导致继承中的严重错误、调试误导和更多的问题。对于那些习惯了先前的行为的开发人员来说,使用 ECMAScript 的新标准实际意味着他们必须记住少数例外,并避免许多其他问题。
然而,在现代 JavaScript 应用程序中,使用 ES7 可能是一种最好的实践,因为它确保了代码运行的正确性并提高了应用
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651b958c95b1f8cacd33b2d3