About the understanding of the default values of es6 function parameters?

var x = 1;
function foo(x, y = function() { x = 2; }) {
  var x = 3;
  y();
  console.log(x);
}

foo() // 3
x // 1

the above is the penultimate example of the scope of the function in the book introduction to es6 written by teacher Ruan Yifeng . Teacher Ruan Yifeng"s explanation is as follows

. In the
above code, the parameters of the function foo form a separate scope. In this scope, you first declare the variable x, and then declare that the default value of the variable yrecoery y is an anonymous function. The variable x inside this anonymous function points to the first parameter x in the same scope. An internal variable x is declared inside the function foo, which is not the same variable as the first parameter x because it is not in the same scope, so after executing y, the values of both the internal variable x and the external global variable x remain unchanged.

the running result in the browser is as expected

Babeles5


The result of

function execution is no longer 3

in the es6 environment.

according to teacher Ruan Yifeng

once the default value of the parameter is set, the parameter forms a separate scope (context) when the function is declared to initialize. When initialization is complete, the scope disappears. This grammatical behavior does not occur when the parameter default value is not set.

so how do you understand the scope of this parameter, and the es6 code changes when it is converted through Babel and put into the browser to run? Does this mean that it is the problem of Babel conversion? So what should be the standard for es6?

Mar.18,2021

The implementation of

Babel is wrong.

this is part of the section of ECMA-262:

.if the function's formal parameters do not include any defaultvalue initializers then the body declarations are instantiated in the same Environment Record as the parameters.If defaultvalue parameter initializers exist, a second Environment Record is created for the body declarations.

". If the function parameter does not contain default parameters, the function body declaration and the parameter are initialized in the same Enviroment Record . Otherwise, a second Enviroment Record will be created for the function body declaration."

here you can simply think of Enviroment Record as a separate scope. is detailed here

so when a function has default parameters, you should create an independent scope for the parameters, and then create the scope of the function body in this scope, so a function declaration with default parameters defined in the global environment produces at least three scopes at run time, which looks like this (the more accurate term for "scope" here is Lexical Enviroment , lexical environment):

clipboard.png

(why at least, because there may be other scopes within function body, which is not the point)

ES Spec specifies this because if the default parameter refers to a variable outside the scope of the function, and there is a variable with the same name inside the function, then the variable actually used should be external, not internal. This is in line with human thinking habits, and you don't use a variable before it is defined.

so if you want to convert a function with default parameters to ES5, you must use another function to isolate the parameter from the function body to achieve scope isolation. Take the practice of the topic as an example, the converted function should look like this:

var x;

function foo(x) {
  // 
  var y;
  // 
  var x;
  

  y = function () { x = 2};
  x = 3;
  
  // yx
  y();
  console.log(x);
}

x = 1;

foo();           // 2
console.log(x);  // 1

so once var x exists in your foo () function, then the x inside the function is a local variable

.

and then condemn one of your points is: can you post code with markdown next time?

Menu