为什么JavaScript在多个属性赋值时连接函数名称?

5
这是一个边缘案例,可能是不良实践,但它让我对一些js内部机制产生了好奇。有人能解释一下为什么Chrome开发工具告诉我我在这里创建了一个名为a.a.b.b的函数吗?

enter image description here

请注意,除非您正在分配属性,否则不会发生这种情况。否则,a和b似乎都是指名为“b”的函数对象:

enter image description here

顺便说一下,我最初遇到了这里,当时是在尝试回答我的自己的问题关于dat.gui.js。


3
你被浏览器控制台的奇怪工作方式所误导了。(这种语言不是你想象中的那样工作。匿名函数实际上没有名称。) - Pointy
3
针对 @Pointy 的观点,如果您尝试调用 a.a.b.b(),会出现 TypeError 错误。 - adamdc78
这与JS内部机制无关,只是为了调试方便而进行的DevTools增强。真正分配的值仍然是匿名函数 - a.a.name会给出空字符串。 - Leo
1个回答

3

这与语言规范无关。

这是为了方便调试而进行的DevTools增强功能,最近在Chrome中进行了移植。

还记得我们以前做过的事情吗?

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

var f = new F();
f.asdf();

在断点调试中,我们可以通过函数调用栈中的名称 _asdf 找到该方法。否则,从 (anonymous function) 列表中找到它会比较麻烦。

enter image description here

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

var a = {}, b = {};
a.a = b.b = function() { debugger; };
a.b = b.a = function _abba() { debugger; };

请记住,这只是DevTools的增强功能,方法仍然是匿名的

a.a.name; // ""
a.b.name; // "_abba"

但是在断点调试中非常有用:

a.a();
a.b();

输入图像描述


编辑:

我不太确定为什么别名会生成为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

还有一件事,当我发现这个功能时,就一直在想 - 这是否意味着Chrome将很快实现ES6?太令人兴奋了!


非常有帮助的答案。我不知怎么开始认为分配给变量的函数不再是匿名的,你纠正了我的理解。我还没有将其标记为正确,因为我仍然不清楚Chrome开发工具为什么会做a.a.b.b这样的事情。你已经说服我这并不重要,但你认为这是意外还是设计上的? - foobarbecue
@foobarbecue 我不确定为什么是 a.a.b.b,但我在我的回答中添加了一些内容,关于我们如何利用这个特性。另一个大胆的猜测是(多么令人兴奋),Chrome 很快就会实现 ES6 class - Leo
有趣...我真的不明白为什么连接事物会意味着实现。你能再解释一下吗?我猜这实际上是Chrome Dev Tools中的某种错误。 - foobarbecue
1
@foobarbecue,我在这里发现了一些有趣的东西:https://code.google.com/p/chromium/issues/detail?id=17356。阅读讨论,特别是#44,#49和#55。所以看起来这更像是一个功能而不是一个错误:D 关于class 的实施,这只是我的猜测。我希望它可以在不久的将来变成现实。 - Leo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接