1

I was doing some exercises in a book and I've came accross this example:

<html>
  <body>
      <script type="text/javascript">
        var canFly = function() { return true;}
        
        window.onload = function() {
          console.log('Assert: "' + window.canFly.name+'"');
        }
      </script>
  </body>
</html>

However upon executing in Chrome 51 and Firefox 46.0.1, I've realized they behave a bit different.

Namely, Chrome seems to return Assert: "canFly" while Firefox returns Assert: "". According to the book, Firefox behavior is the expected one.

My questions is either of these two behaviors the 'correct' one, in reference to the spec?

Daniel Fath
  • 16,453
  • 7
  • 47
  • 82

4 Answers4

4
  • The ES5 spec says nothing about .name properties of functions, therefore it should be undefined.

  • (Some) browsers still implemented function names as a feature, and anonymous functions would have no name, therefore it should be "". Additionally, developer tools would be more clever, and name some anonymous functions for debugging purposes (but not give them a .name property).

  • The ES6 spec gives anonymous function expressions that are assigned to variables a .name property, so it should be "canFly".

Now choose yourself which of those you consider "correct" :-) Your book might be a bit outdated, and FF is a bit behind at implementing this new ES6 feature.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • [Here's a spec link](http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances-name), I'm digging into where the `Function.prototype.name` property is defined. – zzzzBov Jun 09 '16 at 16:36
  • 1
    [Here's the prototype spec link](http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-prototype-object), looks like anonymous functions should have a `name` of `""` per the spec. – zzzzBov Jun 09 '16 at 16:39
  • 1
    @zzzzBov: Have a look [here](http://stackoverflow.com/a/33629506/1048572) and [many other questions](https://stackoverflow.com/search?q=%5Bes6%5D+anonymous+function+.name) where it's mentioned – Bergi Jun 09 '16 at 16:48
3

I think here’s your answer: Function "name" property (ES6).

Basically, it’s the “smarts” of Chrome’s DevTools, and a behavior apparently supported by newer JS standard.

Anton Strogonoff
  • 32,294
  • 8
  • 53
  • 61
2

When you read a book about a web technology that is constantly changing, expect that some or all of the information will be out-of-date.

In ES5 there was no name property defined for function instances, nor was it defined for Function.prototype.


In ES2015, the name property was defined for function instances:

The value of the name property is an String that is descriptive of the function. The name has no semantic significance but is typically a variable or property name that is used to refer to the function at its point of definition in ECMAScript code. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Anonymous functions objects that do not have a contextual name associated with them by this specification do not have a name own property but inherit the name property of %FunctionPrototype%.

it was also defined for function.prototype:

The value of the name property of the Function prototype object is the empty String.

There's also an algorithm defined called SetFunctionName, which appears to handle assigning a name property in a variety of cases, such as when a function is used as part of an object literal.


This is as far down the rabbit hole as I've dug. I would not be surprised if Chrome and Firefox had different levels of support for the SetFunctionName or if there were differences between the ES2015 and ES2017 specs that would lead to the behavior you're seeing.

Community
  • 1
  • 1
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
0

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

var f = function() {};
var object = {
  someMethod: function() {}
};

console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"

It might be helpful to read about inferred function names.

Paul Calabro
  • 1,748
  • 1
  • 16
  • 33