declaring a variable twice in IIFEScope of Default function parameters in javascriptWhy would a JavaScript variable start with a dollar sign?How do you use a variable in a regular expression?What is the scope of variables in JavaScript?How do you check if a variable is an array in JavaScript?How do I declare a namespace in JavaScript?How to determine if variable is 'undefined' or 'null'?Check if a variable is a string in JavaScriptRead environment variables in Node.jsJavaScript check if variable exists (is defined/initialized)Is there a standard function to check for null, undefined, or blank variables in JavaScript?

How is the claim "I am in New York only if I am in America" the same as "If I am in New York, then I am in America?

Can an x86 CPU running in real mode be considered to be basically an 8086 CPU?

Why did the Germans forbid the possession of pet pigeons in Rostov-on-Don in 1941?

N.B. ligature in Latex

Accidentally leaked the solution to an assignment, what to do now? (I'm the prof)

How to type dʒ symbol (IPA) on Mac?

Why are only specific transaction types accepted into the mempool?

Book about a traveler who helps planets in need

A Journey Through Space and Time

Is the language <p,n> belongs to NP class?

How can I fix this gap between bookcases I made?

How to add power-LED to my small amplifier?

Download, install and reboot computer at night if needed

Should I join office cleaning event for free?

Continuity at a point in terms of closure

DOS, create pipe for stdin/stdout of command.com(or 4dos.com) in C or Batch?

When blogging recipes, how can I support both readers who want the narrative/journey and ones who want the printer-friendly recipe?

Representing power series as a function - what to do with the constant after integration?

Why is "Reports" in sentence down without "The"

A newer friend of my brother's gave him a load of baseball cards that are supposedly extremely valuable. Is this a scam?

Is there a familial term for apples and pears?

Example of a relative pronoun

What would happen to a modern skyscraper if it rains micro blackholes?

Do any Labour MPs support no-deal?



declaring a variable twice in IIFE


Scope of Default function parameters in javascriptWhy would a JavaScript variable start with a dollar sign?How do you use a variable in a regular expression?What is the scope of variables in JavaScript?How do you check if a variable is an array in JavaScript?How do I declare a namespace in JavaScript?How to determine if variable is 'undefined' or 'null'?Check if a variable is a string in JavaScriptRead environment variables in Node.jsJavaScript check if variable exists (is defined/initialized)Is there a standard function to check for null, undefined, or blank variables in JavaScript?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








10















I came through this fun quiz on the internet.



console.log((function(x, f = (() => x))
var x;
var y = x;
x = 2;
return [x, y, f()]
)(1))


and the choices were:



  1. [2,1,1]


  2. [2, undefined, 1]


  3. [2, 1, 2]


  4. [2, undefined, 2]


I picked solution 2 TBH, basing that on that x has been redefined, y was declared and defined with no value, and that f has a different scope hence getting the global x memory spot than function x memory spot.



However, I tried it in jsbin.com



and I found it was solution 1, while I was not sure why that happened I messed with the function body and I removed var x from the function body, I found that the response changed to #3 which makes sense as x value changed and hence it showed x and f as 2 and y as 1 which was declared globally.



but still I can't get why it shows 1 instead of undefined.










share|improve this question

















  • 1





    I find the best way to figure these things out is to step through them line by line with a debugger, and/or print out the values after each line.

    – Heretic Monkey
    7 hours ago











  • var x; doesn't define a new variable within the function scope, where var x = somevalue; would

    – Alex
    7 hours ago






  • 2





    @alex it does. ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms I see, would have expected x to be undefined then, implicitly copy the function formal value looks really odd to me.

    – Alex
    7 hours ago






  • 2





    I'm glad this question was asked :)

    – Pointy
    6 hours ago

















10















I came through this fun quiz on the internet.



console.log((function(x, f = (() => x))
var x;
var y = x;
x = 2;
return [x, y, f()]
)(1))


and the choices were:



  1. [2,1,1]


  2. [2, undefined, 1]


  3. [2, 1, 2]


  4. [2, undefined, 2]


I picked solution 2 TBH, basing that on that x has been redefined, y was declared and defined with no value, and that f has a different scope hence getting the global x memory spot than function x memory spot.



However, I tried it in jsbin.com



and I found it was solution 1, while I was not sure why that happened I messed with the function body and I removed var x from the function body, I found that the response changed to #3 which makes sense as x value changed and hence it showed x and f as 2 and y as 1 which was declared globally.



but still I can't get why it shows 1 instead of undefined.










share|improve this question

















  • 1





    I find the best way to figure these things out is to step through them line by line with a debugger, and/or print out the values after each line.

    – Heretic Monkey
    7 hours ago











  • var x; doesn't define a new variable within the function scope, where var x = somevalue; would

    – Alex
    7 hours ago






  • 2





    @alex it does. ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms I see, would have expected x to be undefined then, implicitly copy the function formal value looks really odd to me.

    – Alex
    7 hours ago






  • 2





    I'm glad this question was asked :)

    – Pointy
    6 hours ago













10












10








10


4






I came through this fun quiz on the internet.



console.log((function(x, f = (() => x))
var x;
var y = x;
x = 2;
return [x, y, f()]
)(1))


and the choices were:



  1. [2,1,1]


  2. [2, undefined, 1]


  3. [2, 1, 2]


  4. [2, undefined, 2]


I picked solution 2 TBH, basing that on that x has been redefined, y was declared and defined with no value, and that f has a different scope hence getting the global x memory spot than function x memory spot.



However, I tried it in jsbin.com



and I found it was solution 1, while I was not sure why that happened I messed with the function body and I removed var x from the function body, I found that the response changed to #3 which makes sense as x value changed and hence it showed x and f as 2 and y as 1 which was declared globally.



but still I can't get why it shows 1 instead of undefined.










share|improve this question














I came through this fun quiz on the internet.



console.log((function(x, f = (() => x))
var x;
var y = x;
x = 2;
return [x, y, f()]
)(1))


and the choices were:



  1. [2,1,1]


  2. [2, undefined, 1]


  3. [2, 1, 2]


  4. [2, undefined, 2]


I picked solution 2 TBH, basing that on that x has been redefined, y was declared and defined with no value, and that f has a different scope hence getting the global x memory spot than function x memory spot.



However, I tried it in jsbin.com



and I found it was solution 1, while I was not sure why that happened I messed with the function body and I removed var x from the function body, I found that the response changed to #3 which makes sense as x value changed and hence it showed x and f as 2 and y as 1 which was declared globally.



but still I can't get why it shows 1 instead of undefined.







javascript iife






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 7 hours ago









Hamza MohamedHamza Mohamed

664423




664423







  • 1





    I find the best way to figure these things out is to step through them line by line with a debugger, and/or print out the values after each line.

    – Heretic Monkey
    7 hours ago











  • var x; doesn't define a new variable within the function scope, where var x = somevalue; would

    – Alex
    7 hours ago






  • 2





    @alex it does. ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms I see, would have expected x to be undefined then, implicitly copy the function formal value looks really odd to me.

    – Alex
    7 hours ago






  • 2





    I'm glad this question was asked :)

    – Pointy
    6 hours ago












  • 1





    I find the best way to figure these things out is to step through them line by line with a debugger, and/or print out the values after each line.

    – Heretic Monkey
    7 hours ago











  • var x; doesn't define a new variable within the function scope, where var x = somevalue; would

    – Alex
    7 hours ago






  • 2





    @alex it does. ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms I see, would have expected x to be undefined then, implicitly copy the function formal value looks really odd to me.

    – Alex
    7 hours ago






  • 2





    I'm glad this question was asked :)

    – Pointy
    6 hours ago







1




1





I find the best way to figure these things out is to step through them line by line with a debugger, and/or print out the values after each line.

– Heretic Monkey
7 hours ago





I find the best way to figure these things out is to step through them line by line with a debugger, and/or print out the values after each line.

– Heretic Monkey
7 hours ago













var x; doesn't define a new variable within the function scope, where var x = somevalue; would

– Alex
7 hours ago





var x; doesn't define a new variable within the function scope, where var x = somevalue; would

– Alex
7 hours ago




2




2





@alex it does. ...

– Jonas Wilms
7 hours ago





@alex it does. ...

– Jonas Wilms
7 hours ago













@JonasWilms I see, would have expected x to be undefined then, implicitly copy the function formal value looks really odd to me.

– Alex
7 hours ago





@JonasWilms I see, would have expected x to be undefined then, implicitly copy the function formal value looks really odd to me.

– Alex
7 hours ago




2




2





I'm glad this question was asked :)

– Pointy
6 hours ago





I'm glad this question was asked :)

– Pointy
6 hours ago












2 Answers
2






active

oldest

votes


















11















but still I can't get why it shows 1 instead of undefined.




It's not just you. This is a deep, dark part of the specification. :-)



The key here is that there are two xs. Yes, really. There's the parameter x, and there's the variable x.



A parameter list containing expressions (like f's default value) has its own scope separate from the function body's scope. But prior to parameter lists possibly having expressions, having var x within a function with an x parameter had no effect (x was still the parameter, with the parameter's value). So to preserve that, when there's a parameter list with expressions in it, a separate variable is created and the value of the parameter is copied to the variable at the beginning of the function body. Which is the reason for this seemingly-odd (no, not just seemingly) odd behavior. (If you're the kind who likes to dive into the spec, this copying is Step 28 of FunctionDeclarationInstantiation.)



Since f's default value, () => x, is created within the parameter list scope, it refers to the parameter x, not the var.



So the first solution, [2, 1, 1] is correct, because:




  • 2 was assigned to the var x in the function body. So at the end of the function, the var x is 2.


  • 1 was assigned to y from the var x before x got the value 2, so at the end of the function, y is 1.

  • The parameter x's value has never changed, so f() results in 1 at the end of the function

It's as though the code were written like this instead (I've removed unnecessary parens and added missing semicolons):






console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));






...I removed var x from the function body, I found that the response changed to #3...




#3 is [2, 1, 2]. That's correct, because when you remove the var x from the function, there's only one x, the parameter (inherited by the function body from the parmeter list). So assigning 2 to x changes the parameter's value, which f returns.



Taking the earier example with param_x and var_x, here's what it looks like if you remove the var x; from it:






console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));






Here's an annotated description of the original code (with the extraneous parentheses removed and missing semicolons added):



// /---- the parameter "x"
// v vvvvvvvvvvv--- the parameter "f" with a default value
console.log(function(x, f = () => x) +--- 1, because f is () => x, but that x is the *parameter* x,
// (1));



Final note regarding your title:




declaring a variable twice in IIFE




The variable is only declared once. The other thing is a parameter, not a variable. The distinction is rarely important...this being one of those rare times. :-)






share|improve this answer




















  • 1





    This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

    – Pointy
    6 hours ago











  • @Pointy - Oh, this is much weirder than field declarations. :-D

    – T.J. Crowder
    6 hours ago











  • Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

    – Pointy
    6 hours ago











  • @Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

    – T.J. Crowder
    6 hours ago



















1














The tricky part of that code is that the => function is created as part of a default parameter value expression. In parameter default value expressions, the scope includes the parameters declared to the left, which in this case includes the parameter x. Thus for that reason the x in the => function is in fact the first parameter.



The function is called with just one parameter, 1, so when the => function is called that's what it returns, giving [2, 1, 1].



The var x declaration, as Mr Crowder points out, has the (somewhat weird, at least to me) effect of making a new x in the function scope, into which is copied the value of the parameter x. Without it, there's only the one (the parameter).






share|improve this answer

























  • That still does not explain why removing var x; results in 2, 1, 2 ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

    – Pointy
    7 hours ago











  • I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

    – Jonas Wilms
    7 hours ago











  • It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

    – Jonas Wilms
    6 hours ago











  • @Pointy - It's a very deep, dark part of the spec. :-)

    – T.J. Crowder
    6 hours ago











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55560027%2fdeclaring-a-variable-twice-in-iife%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









11















but still I can't get why it shows 1 instead of undefined.




It's not just you. This is a deep, dark part of the specification. :-)



The key here is that there are two xs. Yes, really. There's the parameter x, and there's the variable x.



A parameter list containing expressions (like f's default value) has its own scope separate from the function body's scope. But prior to parameter lists possibly having expressions, having var x within a function with an x parameter had no effect (x was still the parameter, with the parameter's value). So to preserve that, when there's a parameter list with expressions in it, a separate variable is created and the value of the parameter is copied to the variable at the beginning of the function body. Which is the reason for this seemingly-odd (no, not just seemingly) odd behavior. (If you're the kind who likes to dive into the spec, this copying is Step 28 of FunctionDeclarationInstantiation.)



Since f's default value, () => x, is created within the parameter list scope, it refers to the parameter x, not the var.



So the first solution, [2, 1, 1] is correct, because:




  • 2 was assigned to the var x in the function body. So at the end of the function, the var x is 2.


  • 1 was assigned to y from the var x before x got the value 2, so at the end of the function, y is 1.

  • The parameter x's value has never changed, so f() results in 1 at the end of the function

It's as though the code were written like this instead (I've removed unnecessary parens and added missing semicolons):






console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));






...I removed var x from the function body, I found that the response changed to #3...




#3 is [2, 1, 2]. That's correct, because when you remove the var x from the function, there's only one x, the parameter (inherited by the function body from the parmeter list). So assigning 2 to x changes the parameter's value, which f returns.



Taking the earier example with param_x and var_x, here's what it looks like if you remove the var x; from it:






console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));






Here's an annotated description of the original code (with the extraneous parentheses removed and missing semicolons added):



// /---- the parameter "x"
// v vvvvvvvvvvv--- the parameter "f" with a default value
console.log(function(x, f = () => x) +--- 1, because f is () => x, but that x is the *parameter* x,
// (1));



Final note regarding your title:




declaring a variable twice in IIFE




The variable is only declared once. The other thing is a parameter, not a variable. The distinction is rarely important...this being one of those rare times. :-)






share|improve this answer




















  • 1





    This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

    – Pointy
    6 hours ago











  • @Pointy - Oh, this is much weirder than field declarations. :-D

    – T.J. Crowder
    6 hours ago











  • Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

    – Pointy
    6 hours ago











  • @Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

    – T.J. Crowder
    6 hours ago
















11















but still I can't get why it shows 1 instead of undefined.




It's not just you. This is a deep, dark part of the specification. :-)



The key here is that there are two xs. Yes, really. There's the parameter x, and there's the variable x.



A parameter list containing expressions (like f's default value) has its own scope separate from the function body's scope. But prior to parameter lists possibly having expressions, having var x within a function with an x parameter had no effect (x was still the parameter, with the parameter's value). So to preserve that, when there's a parameter list with expressions in it, a separate variable is created and the value of the parameter is copied to the variable at the beginning of the function body. Which is the reason for this seemingly-odd (no, not just seemingly) odd behavior. (If you're the kind who likes to dive into the spec, this copying is Step 28 of FunctionDeclarationInstantiation.)



Since f's default value, () => x, is created within the parameter list scope, it refers to the parameter x, not the var.



So the first solution, [2, 1, 1] is correct, because:




  • 2 was assigned to the var x in the function body. So at the end of the function, the var x is 2.


  • 1 was assigned to y from the var x before x got the value 2, so at the end of the function, y is 1.

  • The parameter x's value has never changed, so f() results in 1 at the end of the function

It's as though the code were written like this instead (I've removed unnecessary parens and added missing semicolons):






console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));






...I removed var x from the function body, I found that the response changed to #3...




#3 is [2, 1, 2]. That's correct, because when you remove the var x from the function, there's only one x, the parameter (inherited by the function body from the parmeter list). So assigning 2 to x changes the parameter's value, which f returns.



Taking the earier example with param_x and var_x, here's what it looks like if you remove the var x; from it:






console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));






Here's an annotated description of the original code (with the extraneous parentheses removed and missing semicolons added):



// /---- the parameter "x"
// v vvvvvvvvvvv--- the parameter "f" with a default value
console.log(function(x, f = () => x) +--- 1, because f is () => x, but that x is the *parameter* x,
// (1));



Final note regarding your title:




declaring a variable twice in IIFE




The variable is only declared once. The other thing is a parameter, not a variable. The distinction is rarely important...this being one of those rare times. :-)






share|improve this answer




















  • 1





    This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

    – Pointy
    6 hours ago











  • @Pointy - Oh, this is much weirder than field declarations. :-D

    – T.J. Crowder
    6 hours ago











  • Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

    – Pointy
    6 hours ago











  • @Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

    – T.J. Crowder
    6 hours ago














11












11








11








but still I can't get why it shows 1 instead of undefined.




It's not just you. This is a deep, dark part of the specification. :-)



The key here is that there are two xs. Yes, really. There's the parameter x, and there's the variable x.



A parameter list containing expressions (like f's default value) has its own scope separate from the function body's scope. But prior to parameter lists possibly having expressions, having var x within a function with an x parameter had no effect (x was still the parameter, with the parameter's value). So to preserve that, when there's a parameter list with expressions in it, a separate variable is created and the value of the parameter is copied to the variable at the beginning of the function body. Which is the reason for this seemingly-odd (no, not just seemingly) odd behavior. (If you're the kind who likes to dive into the spec, this copying is Step 28 of FunctionDeclarationInstantiation.)



Since f's default value, () => x, is created within the parameter list scope, it refers to the parameter x, not the var.



So the first solution, [2, 1, 1] is correct, because:




  • 2 was assigned to the var x in the function body. So at the end of the function, the var x is 2.


  • 1 was assigned to y from the var x before x got the value 2, so at the end of the function, y is 1.

  • The parameter x's value has never changed, so f() results in 1 at the end of the function

It's as though the code were written like this instead (I've removed unnecessary parens and added missing semicolons):






console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));






...I removed var x from the function body, I found that the response changed to #3...




#3 is [2, 1, 2]. That's correct, because when you remove the var x from the function, there's only one x, the parameter (inherited by the function body from the parmeter list). So assigning 2 to x changes the parameter's value, which f returns.



Taking the earier example with param_x and var_x, here's what it looks like if you remove the var x; from it:






console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));






Here's an annotated description of the original code (with the extraneous parentheses removed and missing semicolons added):



// /---- the parameter "x"
// v vvvvvvvvvvv--- the parameter "f" with a default value
console.log(function(x, f = () => x) +--- 1, because f is () => x, but that x is the *parameter* x,
// (1));



Final note regarding your title:




declaring a variable twice in IIFE




The variable is only declared once. The other thing is a parameter, not a variable. The distinction is rarely important...this being one of those rare times. :-)






share|improve this answer
















but still I can't get why it shows 1 instead of undefined.




It's not just you. This is a deep, dark part of the specification. :-)



The key here is that there are two xs. Yes, really. There's the parameter x, and there's the variable x.



A parameter list containing expressions (like f's default value) has its own scope separate from the function body's scope. But prior to parameter lists possibly having expressions, having var x within a function with an x parameter had no effect (x was still the parameter, with the parameter's value). So to preserve that, when there's a parameter list with expressions in it, a separate variable is created and the value of the parameter is copied to the variable at the beginning of the function body. Which is the reason for this seemingly-odd (no, not just seemingly) odd behavior. (If you're the kind who likes to dive into the spec, this copying is Step 28 of FunctionDeclarationInstantiation.)



Since f's default value, () => x, is created within the parameter list scope, it refers to the parameter x, not the var.



So the first solution, [2, 1, 1] is correct, because:




  • 2 was assigned to the var x in the function body. So at the end of the function, the var x is 2.


  • 1 was assigned to y from the var x before x got the value 2, so at the end of the function, y is 1.

  • The parameter x's value has never changed, so f() results in 1 at the end of the function

It's as though the code were written like this instead (I've removed unnecessary parens and added missing semicolons):






console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));






...I removed var x from the function body, I found that the response changed to #3...




#3 is [2, 1, 2]. That's correct, because when you remove the var x from the function, there's only one x, the parameter (inherited by the function body from the parmeter list). So assigning 2 to x changes the parameter's value, which f returns.



Taking the earier example with param_x and var_x, here's what it looks like if you remove the var x; from it:






console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));






Here's an annotated description of the original code (with the extraneous parentheses removed and missing semicolons added):



// /---- the parameter "x"
// v vvvvvvvvvvv--- the parameter "f" with a default value
console.log(function(x, f = () => x) +--- 1, because f is () => x, but that x is the *parameter* x,
// (1));



Final note regarding your title:




declaring a variable twice in IIFE




The variable is only declared once. The other thing is a parameter, not a variable. The distinction is rarely important...this being one of those rare times. :-)






console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));





console.log(function(param_x, f = () => param_x) 
var var_x = param_x;
var y = var_x;
var_x = 2;
return [var_x, y, f()];
(1));





console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));





console.log(function(param_x, f = () => param_x) 
var y = param_x;
param_x = 2;
return [param_x, y, f()];
(1));






share|improve this answer














share|improve this answer



share|improve this answer








edited 6 hours ago

























answered 7 hours ago









T.J. CrowderT.J. Crowder

699k12312431341




699k12312431341







  • 1





    This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

    – Pointy
    6 hours ago











  • @Pointy - Oh, this is much weirder than field declarations. :-D

    – T.J. Crowder
    6 hours ago











  • Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

    – Pointy
    6 hours ago











  • @Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

    – T.J. Crowder
    6 hours ago













  • 1





    This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

    – Pointy
    6 hours ago











  • @Pointy - Oh, this is much weirder than field declarations. :-D

    – T.J. Crowder
    6 hours ago











  • Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

    – Pointy
    6 hours ago











  • @Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

    – T.J. Crowder
    6 hours ago








1




1





This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

– Pointy
6 hours ago





This is now in my list of "new weird things about JavaScript" alongside the semantics of (not yet really standard) instance property initialization expressions in class declarations.

– Pointy
6 hours ago













@Pointy - Oh, this is much weirder than field declarations. :-D

– T.J. Crowder
6 hours ago





@Pointy - Oh, this is much weirder than field declarations. :-D

– T.J. Crowder
6 hours ago













Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

– Pointy
6 hours ago





Well field declarations are jarring to me because this is the instance, not the this of the surrounding scope as with object initializers. I guess it's not really "weird" if you think of class declarations as being something akin to macro expansion.

– Pointy
6 hours ago













@Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

– T.J. Crowder
6 hours ago






@Pointy - Yeah. I think of them as code that's relocated to the beginning of the constructor (just after the super call if it's a subclass). That's what Java does with instance field initializers and instance initialization blocks (and they're literally copied to the beginning of each constructor in Java; thankfully in JavaScript we just have the one). JavaScript took effectively the same approach.

– T.J. Crowder
6 hours ago














1














The tricky part of that code is that the => function is created as part of a default parameter value expression. In parameter default value expressions, the scope includes the parameters declared to the left, which in this case includes the parameter x. Thus for that reason the x in the => function is in fact the first parameter.



The function is called with just one parameter, 1, so when the => function is called that's what it returns, giving [2, 1, 1].



The var x declaration, as Mr Crowder points out, has the (somewhat weird, at least to me) effect of making a new x in the function scope, into which is copied the value of the parameter x. Without it, there's only the one (the parameter).






share|improve this answer

























  • That still does not explain why removing var x; results in 2, 1, 2 ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

    – Pointy
    7 hours ago











  • I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

    – Jonas Wilms
    7 hours ago











  • It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

    – Jonas Wilms
    6 hours ago











  • @Pointy - It's a very deep, dark part of the spec. :-)

    – T.J. Crowder
    6 hours ago















1














The tricky part of that code is that the => function is created as part of a default parameter value expression. In parameter default value expressions, the scope includes the parameters declared to the left, which in this case includes the parameter x. Thus for that reason the x in the => function is in fact the first parameter.



The function is called with just one parameter, 1, so when the => function is called that's what it returns, giving [2, 1, 1].



The var x declaration, as Mr Crowder points out, has the (somewhat weird, at least to me) effect of making a new x in the function scope, into which is copied the value of the parameter x. Without it, there's only the one (the parameter).






share|improve this answer

























  • That still does not explain why removing var x; results in 2, 1, 2 ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

    – Pointy
    7 hours ago











  • I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

    – Jonas Wilms
    7 hours ago











  • It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

    – Jonas Wilms
    6 hours ago











  • @Pointy - It's a very deep, dark part of the spec. :-)

    – T.J. Crowder
    6 hours ago













1












1








1







The tricky part of that code is that the => function is created as part of a default parameter value expression. In parameter default value expressions, the scope includes the parameters declared to the left, which in this case includes the parameter x. Thus for that reason the x in the => function is in fact the first parameter.



The function is called with just one parameter, 1, so when the => function is called that's what it returns, giving [2, 1, 1].



The var x declaration, as Mr Crowder points out, has the (somewhat weird, at least to me) effect of making a new x in the function scope, into which is copied the value of the parameter x. Without it, there's only the one (the parameter).






share|improve this answer















The tricky part of that code is that the => function is created as part of a default parameter value expression. In parameter default value expressions, the scope includes the parameters declared to the left, which in this case includes the parameter x. Thus for that reason the x in the => function is in fact the first parameter.



The function is called with just one parameter, 1, so when the => function is called that's what it returns, giving [2, 1, 1].



The var x declaration, as Mr Crowder points out, has the (somewhat weird, at least to me) effect of making a new x in the function scope, into which is copied the value of the parameter x. Without it, there's only the one (the parameter).







share|improve this answer














share|improve this answer



share|improve this answer








edited 7 hours ago

























answered 7 hours ago









PointyPointy

321k45461528




321k45461528












  • That still does not explain why removing var x; results in 2, 1, 2 ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

    – Pointy
    7 hours ago











  • I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

    – Jonas Wilms
    7 hours ago











  • It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

    – Jonas Wilms
    6 hours ago











  • @Pointy - It's a very deep, dark part of the spec. :-)

    – T.J. Crowder
    6 hours ago

















  • That still does not explain why removing var x; results in 2, 1, 2 ...

    – Jonas Wilms
    7 hours ago











  • @JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

    – Pointy
    7 hours ago











  • I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

    – Jonas Wilms
    7 hours ago











  • It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

    – Jonas Wilms
    6 hours ago











  • @Pointy - It's a very deep, dark part of the spec. :-)

    – T.J. Crowder
    6 hours ago
















That still does not explain why removing var x; results in 2, 1, 2 ...

– Jonas Wilms
7 hours ago





That still does not explain why removing var x; results in 2, 1, 2 ...

– Jonas Wilms
7 hours ago













@JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

– Pointy
7 hours ago





@JonasWilms you're right; the var declaration must ... do something but it doesn't seem obvious to me what that is. It's as if the var declaration creates a new x in the function scope, but it clearly gets the value of the parameter x anyway (which I'd expect), leaving the parameter apparently in its own scope.

– Pointy
7 hours ago













I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

– Jonas Wilms
7 hours ago





I guess the values are somewhat copied from the default initializers scope to the bodies scope. Im already digging into the spec

– Jonas Wilms
7 hours ago













It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

– Jonas Wilms
6 hours ago





It makes sense. As noted in the spec: NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body. thats reasonable.

– Jonas Wilms
6 hours ago













@Pointy - It's a very deep, dark part of the spec. :-)

– T.J. Crowder
6 hours ago





@Pointy - It's a very deep, dark part of the spec. :-)

– T.J. Crowder
6 hours ago

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55560027%2fdeclaring-a-variable-twice-in-iife%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Best approach to update all entries in a list that is paginated?Best way to add items to a paginated listChoose Your Country: Best Usability approachUpdate list when a user is viewing the list without annoying themWhen would the best day to update your webpage be?What should happen when I add a Row to a paginated, sorted listShould I adopt infinite scrolling or classical pagination?How to show user that page objects automatically updateWhat is the best location to locate the comments section in a list pageBest way to combine filtering and selecting items in a listWhen one of two inputs must be updated to satisfy a consistency criteria, which should you update (if at all)?

Вунгтау (аеропорт) Загальні відомості | Див. також | Посилання | Навігаційне меню10°22′00″ пн. ш. 107°05′00″ сх. д. / 10.36667° пн. ш. 107.08333° сх. д. / 10.36667; 107.0833310°22′00″ пн. ш. 107°05′00″ сх. д. / 10.36667° пн. ш. 107.08333° сх. д. / 10.36667; 107.083337731608Vinh AirportVinh airport facelift improves serviceвиправивши або дописавши їївиправивши або дописавши їїр

Тонконіг бульбистий Зміст Опис | Поширення | Екологія | Господарське значення | Примітки | Див. також | Література | Джерела | Посилання | Навігаційне меню1114601320038-241116202404kew-435458Poa bulbosaЭлектронный каталог сосудистых растений Азиатской России [Електронний каталог судинних рослин Азіатської Росії]Малышев Л. Л. Дикие родичи культурных растений. Poa bulbosa L. - Мятлик луковичный. [Малишев Л. Л. Дикі родичи культурних рослин. Poa bulbosa L. - Тонконіг бульбистий.]Мятлик (POA) Сем. Злаки (Мятликовые) [Тонконіг (POA) Род. Злаки (Тонконогові)]Poa bulbosa Linnaeus, Sp. Pl. 1: 70. 1753. 鳞茎早熟禾 lin jing zao shu he (Description from Flora of China) [Poa bulbosa Linnaeus, Sp. Pl. 1: 70. 1753. 鳞茎早熟禾 lin jing zao shu he (Опис від Флора Китаю)]Poa bulbosa L. – lipnice cibulkatá / lipnica cibulkatáPoa bulbosa в базі даних Poa bulbosa на сайті Poa bulbosa в базі даних «Global Biodiversity Information Facility» (GBIF)Poa bulbosa в базі даних «Euro + Med PlantBase» — інформаційному ресурсі для Євро-середземноморського розмаїття рослинPoa bulbosa L. на сайті «Плантариум»