This is an edge case and probably bad practice, but it made me curious about some js internals. Can anyone explain why chrome dev tools tells me that I have created a function named a.a.b.b here?
Note that this does not happen unless you are assigning to a property. Otherwise both a and b appear to refer to a function object named 'b':
By the way, I originally encountered this here when trying to answer my own question about dat.gui.js .
This has nothing to do with the language spec.
It's a DevTools enhancement for debugging convenience, which is ported recently in Chrome.
Remember what we used to do?
function F() {}
// notice it's a NAMED function expression
F.prototype.asdf = function _asdf() { debugger; };
var f = new F();
f.asdf();
Then in breakpoint debugging, we can find the method by its name _asdf
from function call stack. Otherwise it's the pain in the ass to do that from a list of (anonymous function).
In latest Chrome, when you assign an anonymous function as an object property, an alias will be attached to it.
var a = {}, b = {};
a.a = b.b = function() { debugger; };
a.b = b.a = function _abba() { debugger; };
Remember, it's just a DevTools enhancement, the method remains anonymous:
a.a.name; // ""
a.b.name; // "_abba"
But it's very helpful in breakpoint debugging:
a.a();
a.b();
EDIT:
I'm not very sure why the alias is generated as a.a.b.b
, it looks very easy but kind of... stupid. However, in practice we seldom do a.a = b.b = func...
thing (lucky). Instead, we define a method in one place, and do inheritence when necessary, rather than copy reference directly.
So in a good programming practice, the alias should and would exactly reflect where you define the method. For example, alias Dog.bark
in breakpoint clearly maps to Dog.prototype.bark
in source code, even if it's called on a Puppy
instance, and we don't have to do old school named function expression.
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
One more thing, when I discovered this feature, I can't stop thinking of it - does it imply that Chrome will implement ES6 class very soon? How exciting!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With