Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

var x;
function x() {}; // no error.

But in this case i'm getting Error.

{
  var inside; // re-declaration error.
  function inside() {};
}

expected result should be no error.

like image 528
Ramireddy Samar Avatar asked Jul 12 '19 12:07

Ramireddy Samar


People also ask

Can function and variable have same name?

Variables and functions have separate name spaces, which means a variable and a function can have the same name, such as value and value(), and Mata will not confuse them.

How do you return an error in JavaScript?

In JavaScript error message property is used to set or return the error message. Return Value: It returns a string, representing the details of the error.

What is the difference between VAR and function in JavaScript?

A variable is something, which stores data. A function is a bunch of code, which can be executed, if you call. But a function can be a variable, too, as it stores data and values, too. See the following syntax: var functionname = function(){} .


1 Answers

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 1
  function foo() { // declared in block 1
    return 1;
  }
  console.log("block 1: foo() === 1", foo() === 1);
  
  { // block 2
    function foo() { // declared in block 2
      return 2;
    }
    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 1
  var foo = function() {
    return 1;
  }
  console.log("block 1: foo() === 1", foo() === 1);
  (function() { //block 2
    var foo = function() {
      return 2;
    }
    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:

{ //block
  function foo() { return 1; }
  console.log("block: foo() === 1", foo() === 1);
  
  if (true) { // if block
    function foo() { return 2; }
    console.log("if block: foo() === 2", foo() === 2);
  }
  
  for (var i = 0; i < 1; i++) { // for block
    function foo() { return 3; }
    console.log("for block: foo() === 3", foo() === 3);
  }
  
  switch ("hello world") { // case block
    default:
      function foo() { return 4; }
      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);
}

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

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

like image 160
VLAZ Avatar answered Oct 09 '22 21:10

VLAZ