这是一个边缘案例,可能是不好的做法,但它让我对一些js内部成员感到好奇。谁能解释为什么chrome dev工具告诉我我在这里创建了一个名为a.a.b.b的函数?
请注意,除非您要分配属性,否则不会发生这种情况。否则,a和b似乎都引用名为' b':
的函数对象
顺便说一下,我在尝试回答关于dat.gui.js的here时遇到了这个my own question。
答案 0 :(得分: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
的方法。否则,从(匿名函数)列表中可以解决这个问题。
在最新的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...
事(幸运)。相反,我们在一个地方定义一个方法,并在必要时执行 inheritence ,而不是直接复制引用。
因此,在良好的编程实践中,别名应该并且将准确反映您定义方法的位置。例如,断点中的别名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 ?多么令人兴奋!