【问题标题】:Why does javascript concatenate function names in multiple assignment to properties?为什么javascript在对属性的多个分配中连接函数名称?
【发布时间】:2015-08-13 17:46:22
【问题描述】:

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

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

顺便说一句,我最初在尝试回答my own question about dat.gui.js时遇到了这个here

【问题讨论】:

  • 您被浏览器控制台的奇怪工作方式所误导。 (该语言并没有做你认为它正在做的事情。匿名函数并没有真正的名字。)
  • 对于@Pointy 的观点,如果你尝试调用 a.a.b.b() 你会得到一个 TypeError。
  • 它与 JS 内部无关。这只是 DevTools 的增强,我猜是为了方便调试。真正的赋值仍然是匿名函数 - a.a.name 给你空字符串。

标签: javascript function object


【解决方案1】:

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

还记得我们曾经做过什么吗?

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

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

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

在最新的 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 class?多么令人兴奋!

【讨论】:

  • 非常有帮助的答案。我不知何故开始认为分配给变量的函数不再是匿名的,您已经纠正了我对此的理解。我还没有将其标记为正确,因为我仍然不清楚为什么 Chrome 开发工具会准确地完成 a.a.b.b 的事情。你已经让我相信这并不重要,但你认为这是偶然的,还是故意的?
  • @foobarbecue 我不确定为什么是a.a.b.b,但我在回答中添加了一些内容,关于我们如何利用此功能。另一个大胆的猜想是(多么令人兴奋),Chrome 很快就会实现 ES6 class
  • 有趣...我真的不明白为什么串联的东西会暗示 class 的实现。你能解释更多吗?我的猜测是它实际上是 Chrome 开发工具中的某种错误。
  • @foobarbecue 我在这里发现了一些有趣的东西code.google.com/p/chromium/issues/detail?id=17356。阅读讨论,尤其是#44、#49 和#55。所以它看起来像是一个特性而不是一个错误:D 关于class的实现,这只是我的猜测。我希望它可以在不久的将来成为现实。
猜你喜欢
  • 2013-09-25
  • 1970-01-01
  • 2012-06-15
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 2016-01-05
  • 1970-01-01
相关资源
最近更新 更多