9

I am reading a great book named "Secrets of the JavaScript Ninja" written by John Resig & Bear Bibeaoult. In chapter 3.2, it gives an example;

var canFly = function(){ return true; };

Then it says;

An anonymous function is created and assigned to a global variable named canFly. Because of JavaScript's functional nature, the function can be invoked through this reference as canFly(). In this respect, it's almost functionally equivalent to declaring a named function named "canFly", but not quite. One major difference is that the function's name property is "", not "canFly".

But when I try to execute the example on Chrome's Developer Tools and inspect the name property of the canFly function, it returns the value "canFly" instead of an empty string.

canFly.name;
// > "canFly"

Did anonymous functions assigned to variables have no names in the earlier days? If so, what has changed? Or did the authors make a mistake?

aib
  • 45,516
  • 10
  • 73
  • 79
Yusuf Yalim
  • 118
  • 6
  • 1
    I can't remember where I read it but I remember reading that in new versions of Node/V8 even anonymous functions when assigned to a variable will get the variable name. Will post an answer when I find a link. – Aron Jul 17 '17 at 14:42
  • 9
    [*Inferred function names*: Variables and methods can infer the name of an anonymous function from its syntactic position (new in ECMAScript 2015)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Inferred_function_names) – Alex K. Jul 17 '17 at 14:42
  • 1
    There we go. Thanks @AlexK. – Aron Jul 17 '17 at 14:42

2 Answers2

4

In theory anonymous functions are anomymous, meaning nameless. This was how it was originally implemented and for more than ten years everybody was fine with this.

Then two things happened: the whole Web2.0/ajax movement where people started implementing UI features commonly found on desktop apps in web pages and node.js. These two in combination forced more and more developers to treat javascript as a serious language and once people got comfortable with javascript they started writing really large codebases.

This led to complaints about the debuggability of javascript. There were numerous from not having any useful debugger (which led us to really good debuggers in browsers that is in my opinion second best only to MS Visual Studio) to not knowing what function a console.log comes from (because they're anonymous).

This led to browser and js engine developers to implement code that tries to guess the "name" of nameless functions.

In theory this feature is wrong because you can't always guarantee that the name you're guessing is how the function is called (for example if the function is assigned to several different variables). In practice something that works 90% of the time is better than nothing at all.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • 1
    Interestingly John Resig's book was published in 2008 so that gives us a rough timeline of between 2008 and 2017 for when this feature was first implemented. I believe if you're really curious you can dig around the source code of the various js engines for code commits. Apple's javascriptcore (nitro), Google's v8 and Microsoft's chakracore are all open source. – slebetman Jul 17 '17 at 15:31
  • Thanks a lot! Looks like I need to learn C/C++ to understand source code of browser engines but, I think, it is a must to get a deeper understanding of the answer to my question and how JS actually works behind scenes. – Yusuf Yalim Jul 19 '17 at 09:44
2

Here's a slightly tweaked version of your test code that gives a clue that .name may just be trying really hard to be helpful:

var canFly = function () {};
var areYouSure = function yesIAm(){};
console.log(canFly.name);
console.log(areYouSure.name);
console.log((function (){}).name);

Checking for details at MDN we can see it used to be a non-standard property:

The function.name property returns the name of the function.

... that made its way into ES2015 (emphasis mine):

Variables and methods can infer the name of an anonymous function from its syntactic position (new in ECMAScript 2015).

So it returns the name but, when it can't, it tries guessing.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • 1
    Thanks! This means anonymous functions have empty `name` property only if they haven't assigned to a variable. – Yusuf Yalim Jul 19 '17 at 09:23