为什么 javascript 中的匿名函数有名字?

Why do anonymous functions in javascript have names?

我正在读一本名为 "Secrets of the JavaScript Ninja" 的好书,作者是 John Resig 和 Bear Bibeault。在3.2章节中,给出了一个例子;

var canFly = function(){ return true; };

然后它说;

An anonymous function is created and assigned to a global variable named canFly. Because of JavaScript's functional nature, the function can be invoked through this reference as canFly(). In this respect, it's almost functionally equivalent to declaring a named function named "canFly", but not quite. One major difference is that the function's name property is "", not "canFly".

但是当我尝试在 Chrome 的开发者工具上执行示例并检查 canFly 函数的 name 属性 时,它 returns 值 "canFly" 而不是空字符串。

canFly.name;
// > "canFly"

早期赋值给变量的匿名函数是没有名字的吗?如果是这样,发生了什么变化?还是作者弄错了?

理论上匿名函数是匿名的,意思是无名。这就是它最初的实现方式,十多年来,每个人都对此表示满意。

然后发生了两件事:整个 Web2.0/ajax 运动,人们开始在网页和 node.js 的桌面应用程序中实现 UI 常见的功能。这两者的结合迫使越来越多的开发人员将 javascript 视为一种严肃的语言,一旦人们对 javascript 感到满意,他们就会开始编写非常大的代码库。

这导致了对 javascript 的可调试性的抱怨。从没有任何有用的调试器(这导致我们在浏览器中使用了非常好的调试器,在我看来仅次于 MS Visual Studio)到不知道 console.log 来自什么功能(因为他们是匿名的)。

这导致浏览器和 js 引擎开发人员实现了试图猜测 "name" 无名函数的代码。

理论上这个特性是错误的,因为你不能总是保证你猜的名字就是函数的调用方式(例如,如果函数被分配给几个不同的变量)。在实践中,90% 的时间都有效的东西总比什么都没有好。

这是您的测试代码的一个稍微调整的版本,它提供了一个线索,表明 .name 可能只是非常努力地提供帮助:

var canFly = function () {};
var areYouSure = function yesIAm(){};
console.log(canFly.name);
console.log(areYouSure.name);
console.log((function (){}).name);

MDN 查看详细信息,我们可以看到它曾经是一个非标准 属性:

The function.name property returns the name of the function.

...进入 ES2015(强调我的):

Variables and methods can infer the name of an anonymous function from its syntactic position (new in ECMAScript 2015).

所以它 returns 名字但是,当它不能时,它会尝试猜测。