Why is a function declaration within a condition block hoisted to function scope in Chrome but not Firefox?

Asked
Active3 hr before
Viewed126 times

8 Answers

function
90%

ECMAScript 5, the current official specification of the JavaScript language, does not define the behavior for function declarations inside blocks.,Should the function declaration be hoisted to the top of the current function/global scope? Make sure the function declaration is not directly inside of a block.,As ES5 does not define the behavior for function declarations inside blocks while allowing proprietary extensions, there are technically no "rights" or "wrongs". Consider them "unspecified behavior" which is not portable across different ES5-compliant environments.,As per ECMAScript 6, function declarations are block-scoped, so Firefox implements the correct behavior ES6-wise.

FunctionDeclarations are only allowed to appear in Program or FunctionBody. Syntactically, they can not appear in Block ({ ... }) — such as that of if, while or for statements. This is because Blocks can only contain Statements, not SourceElements, which FunctionDeclaration is. If we look at production rules carefully, we can see that the only way Expression is allowed directly within Block is when it is part of ExpressionStatement. However, ExpressionStatement is explicitly defined to not begin with "function" keyword, and this is exactly why FunctionDeclaration cannot appear directly within a Statement or Block (note that Block is merely a list of Statements).

{
   ...
}

FunctionDeclarations are only allowed to appear in Program or FunctionBody. Syntactically, they can not appear in Block ({ ... }) — such as that of if, while or for statements. This is because Blocks can only contain Statements, not SourceElements, which FunctionDeclaration is. If we look at production rules carefully, we can see that the only way Expression is allowed directly within Block is when it is part of ExpressionStatement. However, ExpressionStatement is explicitly defined to not begin with "function" keyword, and this is exactly why FunctionDeclaration cannot appear directly within a Statement or Block (note that Block is merely a list of Statements).

if

FunctionDeclarations are only allowed to appear in Program or FunctionBody. Syntactically, they can not appear in Block ({ ... }) — such as that of if, while or for statements. This is because Blocks can only contain Statements, not SourceElements, which FunctionDeclaration is. If we look at production rules carefully, we can see that the only way Expression is allowed directly within Block is when it is part of ExpressionStatement. However, ExpressionStatement is explicitly defined to not begin with "function" keyword, and this is exactly why FunctionDeclaration cannot appear directly within a Statement or Block (note that Block is merely a list of Statements).

while

FunctionDeclarations are only allowed to appear in Program or FunctionBody. Syntactically, they can not appear in Block ({ ... }) — such as that of if, while or for statements. This is because Blocks can only contain Statements, not SourceElements, which FunctionDeclaration is. If we look at production rules carefully, we can see that the only way Expression is allowed directly within Block is when it is part of ExpressionStatement. However, ExpressionStatement is explicitly defined to not begin with "function" keyword, and this is exactly why FunctionDeclaration cannot appear directly within a Statement or Block (note that Block is merely a list of Statements).

for
load more v
88%

ECMAScript 5, the current official specification of the JavaScript language, does not define the behavior for function declarations inside blocks.,As per ECMAScript 6, function declarations are block-scoped, so Firefox implements the correct behavior ES6-wise.,Should the function declaration be hoisted to the top of the current function/global scope? Make sure the function declaration is not directly inside of a block.,As ES5 does not define the behavior for function declarations inside blocks while allowing proprietary extensions, there are technically no "rights" or "wrongs". Consider them "unspecified behavior" which is not portable across different ES5-compliant environments.

Why the following codes output different results between Chrome and Firefox?

f = function() {
   return true;
};
g = function() {
   return false;
};
(function() {
   if (g() && [] == ![]) {
      f = function f() {
         return false;
      };

      function g() {
         return true;
      }
   }
})();
console.log(f());
72%

Functions can be conditionally declared, that is, a function statement can be nested within an if statement, however the results are inconsistent across implementations and therefore this pattern should not be used in production code. For conditional function creation, use function expressions instead. , The function declaration (function statement) defines a function with the specified parameters. , By default, functions return undefined. To return any other value, the function must have a return statement that specifies the value to return. , A function created with a function declaration is a Function object and has all the properties, methods and behavior of Function objects. See Function for detailed information on functions.

function name([param[, param, [..., param]]]) {
   [statements]
}
load more v
65%

then (I believe) all browsers pre ES2015 (IE10-, WebKit, Firefox and Chrome) would alert "hey" just once. This is the long-standing web-compatible intersection, as far as I can tell.,1 - 20 2 - function () {}, Actions , Actions

var foo = function() {
   foo = ...
}
load more v
75%

As discussed in our JavaScript Hiring Guide, a common source of confusion among JavaScript developers (and therefore a common source of bugs) is assuming that JavaScript creates a new scope for each code block. Although this is true in many other languages, it is not true in JavaScript. Consider, for example, the following code:,As JavaScript coding techniques and design patterns have become increasingly sophisticated over the years, there’s been a corresponding increase in the proliferation of self-referencing scopes within callbacks and closures, which are a fairly common source of “this/that confusion”.,Memory leaks are almost inevitable JavaScript problems if you’re not consciously coding to avoid them. There are numerous ways for them to occur, so we’ll just highlight a couple of their more common occurrences.,Objects are kept in memory at least as long as they are accessible from any of the roots through a reference, or a chain of references.

Consider this example code snippet:

Game.prototype.restart = function() {
   this.clearLocalStorage();
   this.timer = setTimeout(function() {
      this.clearBoard(); // what is "this"?
   }, 0);
};
load more v
40%

If a variable is declared inside a code block {...}, it’s only visible inside that block.,The function sayHi is declared inside the if, so it only lives inside it. There is no sayHi outside.,Variables, declared with const, behave the same, so this article is about const too.,That’s because there’s no local variable i inside shooter functions. When such a function is called, it takes i from its outer lexical environment.

{
   // do some job with local variables that should not be seen outside

   let message = "Hello"; // only visible in this block

   alert(message); // Hello
}

alert(message); // Error: message is not defined
load more v
22%

Similar to let, the scope of the const variables is also blocked.,So var variables hoist to the top of its scope and initialize with a value of undefined.,As is evident from the above screenshot, the value of a variable declared using var is printed as "undefined", if we access it before its declaration.,The above screenshot clearly shows that the variables declared using "let" are block-scoped and can't access outside the block in which the declaration happens.

Syntax:

var variable = value;
load more v
60%

The semantics are similar to the with statement of Pascal. ,The syntax of the JavaScript switch statement is as follows: ,Every function in JavaScript is an instance of the Function constructor: ,with the suggestion that the preceding statement be terminated with a semicolon.

var a = 5;
console.log(a); // 5
console.log(A); // throws a ReferenceError: A is not defined
load more v

Other "function-undefined" queries related to "Why is a function declaration within a condition block hoisted to function scope in Chrome but not Firefox?"