为什么javascript会在属性的多个赋值中连接函数名?

foo*_*cue 5 javascript function object

这是一个边缘案例,可能是不好的做法,但它让我对一些js内部成员感到好奇.谁能解释为什么chrome dev工具告诉我我在这里创建了一个名为aabb的函数?

在此输入图像描述

请注意,除非您要分配属性,否则不会发生这种情况.否则,a和b似乎都引用名为'b'的函数对象:

在此输入图像描述

顺便说一句,我最初遇到这个在这里要回答的时候我自己的问题有关dat.gui.js.

Leo*_*Leo 3

这与语言规范无关。
它是为了调试方便而对 DevTools 进行的增强,最近已在 Chrome 中移植。

还记得我们以前做过什么吗?

function F() {}
// notice it's a NAMED function expression
F.prototype.asdf = function _asdf() { debugger; }; 

var f = new F();
f.asdf();
Run Code Online (Sandbox Code Playgroud)

_asdf然后在断点调试中,我们可以通过函数调用堆栈中的方法名称找到该方法。否则,从(匿名函数)列表中执行此操作是很痛苦的。

在此输入图像描述

在最新的 Chrome 中,当您将匿名函数分配为对象属性时,将为其附加一个别名。

var a = {}, b = {};
a.a = b.b = function() { debugger; };
a.b = b.a = function _abba() { debugger; };
Run Code Online (Sandbox Code Playgroud)

请记住,这只是 DevTools 的增强功能,该方法保持匿名

a.a.name; // ""
a.b.name; // "_abba"
Run Code Online (Sandbox Code Playgroud)

但对于断点调试很有帮助:

a.a();
a.b();
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


编辑:

我不太确定为什么别名生成为a.a.b.b,它看起来很简单,但有点......愚蠢。然而,在实践中我们很少做a.a = b.b = func...这样的事情(幸运的是)。相反,我们在一处定义一个方法,并在必要时进行继承,而不是直接复制引用。

因此,在良好的编程实践中,别名应该并且会准确反映您定义方法的位置。例如,Dog.bark断点中的别名清楚地映射到Dog.prototype.bark源代码中,即使它是在Puppy实例上调用的,而且我们不必执行老式的命名函数表达式。

function Dog() {}
Dog.prototype.bark = function() { alert("Woof!") }; // anonymous function expression here
function Puppy() {}
Puppy.prototype = new Dog();

(new Puppy()).bark(); // break point alias -> Dog.bark
Run Code Online (Sandbox Code Playgroud)

还有一件事,当我发现这个功能时,我无法停止思考——这是否意味着 Chrome很快就会实现 ES6类?多么激动人心!