1
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

  1. From the error in show1, I think variable x is predeclared in this Function scope. So 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. Why the results of show2 and show3 are different.
BAKE ZQ
  • 765
  • 6
  • 22
  • Also relevant: [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – VLAZ Oct 03 '19 at 10:37
  • 1
    But basically: 1. you cannot redeclare using `let` or `const`, which is why you get an error. 2. You aren't redeclaring - `x` is declared as a *parameter* which is also a binding in the context. 3. you can redeclare using `var`. – VLAZ Oct 03 '19 at 10:38
  • @VLAZ How can I reproduce this kind of binding? – BAKE ZQ Oct 03 '19 at 10:40
  • *temporary dead zone where parameter variables are declared and initialized in this scope when there are parameters with default values.* is a very strange sentence. I'm really not sure what your getting at here – Liam Oct 03 '19 at 10:40
  • @BAKEZQ which one? – VLAZ Oct 03 '19 at 10:40
  • @VLAZ `x is declared as a parameter which is also a binding in the context` – BAKE ZQ Oct 03 '19 at 10:43
  • @BAKEZQ ah, sorry "binding" is basically "variable". It's the technical name for it because you have a *BindingContext* where each variable is an entry. But I'm not sure what you want to re-create for 2. - declaring a parameter `function f1(x)` is pretty much the same as having `function f2() { var x; }` they are both variables (bindings) in the context. The major difference is how the value would be assigned, e.g., `f1("hello")` will make `x === "hello"` but you have to manually assign `x` in `f2`. – VLAZ Oct 03 '19 at 10:46
  • @VLAZ I have no idea why the assignment of `x` in the temporary zone will change the `x` in this function. This does not work: `var a = 1; var b =a; b = 4;` – BAKE ZQ Oct 03 '19 at 11:31
  • @Liam Just want to make a point that these two scopes are different. I expect that the `x` in the function will be equal to 3 no matter if `x` in the parameter scope is changed. – BAKE ZQ Oct 03 '19 at 11:34
  • @VLAZ According to this https://stackoverflow.com/questions/6888506/redeclaring-a-javascript-variable. Re-declaration will not lose its value. So there will be no difference between show2 and show2. But that's not the case. – BAKE ZQ Oct 03 '19 at 11:41
  • "*Why the results of `show2` and `show3` are different.*" because the `x` is a global in `show2`, and in the callback `y`, so they both refer to the exact same variable. In `show3` you declare a *separate* variable`var x` that now lives in the scope of the current function. The callback `y` has its own scope which is not within the `show3` function's scope, therefore the `x` there does not refer to the `x` within `show3`. The temporal dead zone has no effect unless you use `let` or `const`, again in `show1` the problem is not TDZ it's redeclaration. – VLAZ Oct 03 '19 at 14:43
  • @VLAZ Thanks, I posted a new question as I thought you are not gonna answer my question. I am clearer right now from the answer in this question https://stackoverflow.com/questions/58219009/if-re-declaration-with-var-will-have-effect-on-existed-variable and your comments. – BAKE ZQ Oct 03 '19 at 14:56

0 Answers0