Skip to content Skip to sidebar Skip to footer

A Variable And Function With Same Name Returns An Error Inside A Block

If we declare a variable and a function with same name, it is accepting re-declaration. But when we do the same thing inside a block, it shows re-declaration error. Code: But in t

Solution 1:

This is an EcmaScript 6 change. From ES6 onwards it's no longer allowed to have duplicate bindings within a block scope.

The ES5 spec does not have such a restriction but in the ES6 spec the semantics have been changed:

13.2.1 Static Semantics: Early Errors

Block : { StatementList }

  • It is a Syntax Error if the LexicallyDeclaredNames of StatementList contains any duplicate entries.

  • It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList also occurs in the VarDeclaredNames of StatementList.

The first part is relevant - LexicallyDeclaredNames contains all declarations found within the code inside the block.

Presumably, this is part of a change in semantics function declarations in ES6, since now they can be block scoped:

{ //block 1functionfoo() { // declared in block 1return1;
  }
  console.log("block 1: foo() === 1", foo() === 1);
  
  { // block 2functionfoo() { // declared in block 2return2;
    }
    console.log("block 2: foo() === 2", foo() === 2);
  }
  
  console.log("block 1: foo() === 1", foo() === 1);
}

This is a syntactic sugar over this equivalent ES5 code:

(function() { //block 1var foo = function() {
    return1;
  }
  console.log("block 1: foo() === 1", foo() === 1);
  (function() { //block 2var foo = function() {
      return2;
    }
    console.log("block 2: foo() === 2", foo() === 2);
  })();
  console.log("block 1: foo() === 1", foo() === 1);
})();

However, this feature cannot work with duplicate names.

The same behaviour persists for any block, including other types of block statements. Here is an example:

{ //blockfunctionfoo() { return1; }
  console.log("block: foo() === 1", foo() === 1);
  
  if (true) { // if blockfunctionfoo() { return2; }
    console.log("if block: foo() === 2", foo() === 2);
  }
  
  for (var i = 0; i < 1; i++) { // for blockfunctionfoo() { return3; }
    console.log("for block: foo() === 3", foo() === 3);
  }
  
  switch ("hello world") { // case blockdefault:
      functionfoo() { return4; }
      console.log("case block: foo() === 4", foo() === 4);
  }
  
  console.log("block: foo() === 1", foo() === 1);
}

However, it should be noted that duplicate declaration of the same type (var or function) do not lead to an error:

{
  var foo = 1;
  var foo = 2;
  
  console.log("foo ->", foo);
}

{
  functionbar() { return"a"; }
  functionbar() { return"b"; }
  
  console.log("bar() ->", bar());
}

So, it seems like they aren't treated as different declarations but overwriting the same lexically declared name.

Solution 2:

While exploring this further I came across this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError

The funny thing is that my result is different than theirs for this situation:

try{
        eval(`{
            var x;
            function x(){};
        }`);
    }catch(e){
        console.log(e instanceofSyntaxError);
        console.log(e.message);                // "Hello"console.log(e.name);                   // "SyntaxError"console.log(e.fileName);               // "someFile.js"console.log(e.lineNumber);             // 10console.log(e.columnNumber);           // 0console.log(e.stack);                  // "@Scratchpad/2:11:9\n"
    }

Result:

true// instanceof SyntaxError06:01:10.526VM3194:22Identifier'x' has already been declared // e.message06:01:10.527VM3194:23SyntaxError// e.name06:01:10.527VM3194:24undefined// e.filename06:01:10.527VM3194:25undefined// e.lineNumber06:01:10.527VM3194:26undefined// e.columnNumber06:01:10.527VM3194:27SyntaxError: Identifier'x' has already been declared at VM3194:16// e.stack

Post a Comment for "A Variable And Function With Same Name Returns An Error Inside A Block"