Function declarations in Javascript
First, let's look at a piece of code:
1.f = function() {return true;}; 2.g = function() {return false;}; 3.(function() { 4. if (g() && [] == ![]) { 5. f = function f() {return false;}; 6. function g() {return true;} 7. } 8.})(); 9.console.log(f());
Understanding the above code has several key points:
4th lines of code, if condition [] =! [], Including the falsy value, = Operator logic about function declarations, if condition in g ()
Let's talk about the answer first. In fact, this code returns false in chrome and true in firefox. Why are there different results? Let's see and analyze it.
First, let's see [] =! [] This very strange comparative value. Here we use an empty array to compare it with the reverse value of an empty array. It seems to be false at first. However, its value is true. First, let's look at the right! []: Returns the inverse of an empty array. This means that the empty array must be converted to a boolean value and then reversed. In javascript, all objects are used as boolean values, both indicate true, and an empty array is also an object. Therefore, if an empty array is true, the inverse of an empty array is equivalent! True, so ,! The value of [] is false.
Now that the right side is false, we are looking at [] = false. Didn't we just say that the empty array is true, obviously, this comparison is true = false, that is, false is returned, right? But no, this comparison will return true. Is it crazy? Calm down. According to ECMAScript's = specification, such an expression eventually does this.
Convert false on the right to a value 0 and convert the object on the left to a string. convert an empty array to a string, that is, convert an empty string to a value, and the result is 0 to 0 = 0, to return true, the key here is step 1. The array is converted to an empty string, which is actually a falsy value.
As for the inconsistency between chrome and firefox, the declaration of the 6th-line code function g is in the block.
ECMAScript 5, the current official specification of the JavaScript language, does not define the behavior for function declarations inside blocks.
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 ).
However, according to ECMA6, quoting the ECMAScript 6 draft-B .3.3 Block-Level Function Declarations Web Legacy Compatibility Semantics:
Prior to the Sixth Edition, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an element of a Block statement's StatementList. however, support for that form of FunctionDeclaration was an allowable extension and most browser-hosted ECMAScript implementations permitted them. unfortunately, the semantics of such declarations differ among those implementations. [...]
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 guest SS different ES5-compliant environments.
Therefore, do not place the function declaration in the block. Remember !!!