Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: Inconsistency when assigning a named function to a variable (named function expression)

Can anyone explain the difference in behaviour between Internet Explorer and Firefox in regards to the below:

var myNamespace = (function () {
  var exposed = {};

  exposed.myFunction = function myFunction () {
    return "Works!";
  }

  console.log(myFunction()); 
  // IE: "Works!"
  // Firefox: ReferenceError: myFunction is not defined

  console.log(exposed.myFunction());
  // IE: "Works!"
  // FF: "Works!"

  return exposed;
})();

console.log(myNamespace.myFunction()); 
// IE: "Works!"
// FF: "Works!"

In internet explorer this method allows me to call my function from inside my namespace function by using either myFunction() or exposed.myFunction().

Outside my namepsace function I can use myNamespace.myFunction()

In Firefox, the results are the same with the exception of the bare named function call which does not work.

Should it work? If it shouldn't, then why not?

If it should then is this a known bug?

like image 730
michaelward82 Avatar asked Feb 06 '13 15:02

michaelward82


People also ask

What is named function expression in JavaScript?

Named Functions: In JavaScript, named functions are simply a way of referring to a function that employs the function keyword followed by a name that can be used as a callback to that function. Normal functions with a name or identifier are known as named functions.

What is the difference between function expression and function declaration in JavaScript?

The main difference between a function expression and a function declaration is the function name, which can be omitted in function expressions to create anonymous functions. A function expression can be used as an IIFE (Immediately Invoked Function Expression) which runs as soon as it is defined.

What is the difference between function expression and function statement?

A Function Expression works just like a function declaration or a function statement, the only difference is that a function name is NOT started in a function expression, that is, anonymous functions are created in function expressions.

Why are function expressions not hoisted?

Function expressions aren't added to the scope at all, hoisted or otherwise. This is because they are being used as a value, as opposed to function declarations, whose purpose is to create functions you can call by name.


1 Answers

To prevent false information:

IE has a problem with named function expressions which is what you have. The name of the function should only be available inside the function. From the specification:

The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

where FunctionExpression is defined as:

FunctionExpression :
     function Identifieropt( FormalParameterListopt ) { FunctionBody }

But in IE, instead of making the name only available inside the function, it creates two different function objects, one assigned to the variable and the other to the name you gave the function. The following will yield false in IE (and throw an error in other browsers):

exposed.myFunction === myFunction;

It's a known bug and if you have to code for (older versions of) IE, you better avoid named function expressions.


Related question:

  • detachEvent not working with named inline functions
  • Named Function Expressions in IE, part 2
like image 139
Felix Kling Avatar answered Oct 04 '22 10:10

Felix Kling