Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If re-declaration with var will have effect on existed variable

const show1 = function(x, y = () => {x = 2; return x;}) {
    let x = 3;
    console.log(y());
    console.log(x);
};
show1();

const show2 = function(x, y = () => {x = 2; return x;}) {
    x = 3;
    console.log(y());
    console.log(x);
};
show2();

const show3 = function(x, y = () => {x = 2; return x;}) {
    var x = 3;
    console.log(y());
    console.log(x);
};
show3();

output

show1: Uncaught SyntaxError: Identifier 'x' has already been decalred;
show2: 2 2
show3: 2 3

Question

I was informed that there is a temporary dead zone where parameter variables are declared and initialized. See https://exploringjs.com/es6/ch_variables.html#sec_parameters-as-variables. So there are two scopes here, one is the parameter scope and the other is function scope.

  1. From the error in show1, I thought that there is a x variable already declared in this function.
  2. According to Redeclaring a javascript variable. The re-declaration won't do anything to x(with var). Why the results of show2 and show3 are different.

I posted the same question here If the variables are already declared at the beginning of function execution which was masked as duplicate. But I couldn't find anything useful for my doubt.

like image 732
BAKE ZQ Avatar asked Oct 03 '19 12:10

BAKE ZQ


People also ask

What happens when the var keyword is omitted when declaring and initializing a variable?

If you declare a variable, without using "var", the variable always becomes GLOBAL.

Can var be reassigned?

Once you've declared a variable with var or let , you can reassign a new value to the variable in your programming flow. It is possible if the variable is accessible to assign a value. But with const , you can't reassign a new value at all.

Can you access variable declared with var before it is declared?

Yes, you can use a JavaScript variable before it is declared, with a technique called hoisting.

Can we Redeclare a variable in JavaScript?

You cannot accidentally redeclare a variable.


1 Answers

show1 throws an error because variables declared with let or const cannot have any other variables with the same name initialized in that block (whether in an argument list or with const / let / var).


Variables referenced by default parameters have odd scoping rules. Every argument essentially creates another block that that argument name can be defined in. So

const show3 = function(x, y = () => { x = 2; return x; }) {

is somewhat like (forgive the psuedo-code):

const show3 = < function >{
  let x = firstArg;
  {
    let y = secondArg === undefined ? () => { x = 2; return x; } : secondArg;
    {
      // function body

When you simply assign to a variable name in the argument list, that argument will be overwritten. But when you use syntax to initialize a new variable (with var), you've created another binding for that variable name, which is only visible inside the function body:

const show3 = {
  let x = firstArg;
  {
    let y = secondArg === undefined ? () => { x = 2; return x; }
    // the x referenced in the above line references the outer x, the first argument
    {
      // function body

      // since "var x" is declared here, any references to "x" in this block
      // will only reference the inner x
      // but not the outer x
      var x = /* something */

So, your show2 is reassigning the parameter named x to 3 in the first line of the function body. In contrast, show3 is creating a new variable binding with the same name of x, while the y function's reference to x is referencing the argument x, which is different.

like image 79
CertainPerformance Avatar answered Oct 07 '22 02:10

CertainPerformance