Afternoon read a chapter ECMA-262 by Dmitry Soshnikov, now a little to summarize the parameters in the ES6 in the default values and the resulting parameter intermediate scope.
Original address: http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/# Conditional-intermediate-scope-for-parameters
Parameter default values in ES6 are similar to other languages, and are assigned directly after the parameters:
1 function log (message, level = ' warning ') {2 Console.log (level, ': ', message); 3 }4 5// Warning:low memory6// Error:out of Memory
But a little bit different from Python, the default value for Python is calculated at the time of the function definition and then saved as a __defaults__ parameter of the function. When the function executes, the action on the parameter pointing to this default value also causes the default value to change.
This creates the following problem:
1def foo (x = []):2X.append (1)3 returnx4 5 # We can see that defaults is created once, when6# thefunctionis defined, and is stored as7# Just a property of thefunction8 print (foo.__defaults__) # ([],)9 TenFoo () # [1] OneFoo () # [1, 1] AFoo () # [1, 1, 1] - -# The reason for ThisAs we said: thePrint (foo.__defaults__) # ([1, 1, 1],)
The workaround is to use the special constant none as the default value, and then judge and initialize the true default value within the function.
1def foo (x =None):2 ifx is None:3x = []4X.append (1)5 print (x)6 7 print (foo.__defaults__) # (None,)8 9Foo () # [1]TenFoo () # [1] OneFoo () # [1] A -Print (foo.__defaults__) # ([None],)
The implementation of ES6 is the calculation of the default value that is performed every time the function is called, ensuring that the default value is not changed during the previous execution.
Tdz of parameters (temporal Dead Zone)
The tdz referred to in ES6 refers to a program in which variables or parameters cannot be accessed until the area of initialization is completed.
Therefore, in the following paragraph, the default value of the parameter cannot be set to the parameter itself.
1 var x = 1; 2 3 function // throws! 4 ... 5 }
The default value, X, in =x is resolved in the scope of the parameter, not the global scope. So at this point x is in TDZ and therefore cannot be accessed, so it cannot be assigned to x itself as the default value.
1 function // OK 2 ... 3 }
This notation is possible because X has been initialized to undefined before assigning to Y.
Conditional parameter Intermediate scope
When at least one variable has a default value, ES6 defines an intermediate scope to store these parameter variables, and this scope is not shared with the scope of the function body, which is a major difference from the ES5.
1 varx = 1;2 3 functionFoo (x, y =function() {x = 2; }) {4 varx = 3;5Y ();//is ' x ' shared?6Console.log (x);//No, still 3, not 27 }8 9 foo ();Ten One //and the outer ' x ' is also left untouched AConsole.log (x);//1
In this case, there are three scopes: global scope, parameter scope, and scope of the function ontology
1 : // inner2function// params3// Global
At this point in function y, the value of x is resolved in its own scope, which is the scope of the parameter.
If Transpiling (a language compiled from one language to another at the same level of abstraction) becomes ES5, the three-tier scope is clearer:
1 //ES62 functionFoo (x, y =function() {x = 2; }) {3 varx = 3;4Y ();//is ' x ' shared?5Console.log (x);//No, still 3, not 26 }7 8 //Compiled to ES59 functionfoo (x, y) {Ten //Setup defaults. One if(typeofy = = ' undefined ') { Ay =function() {x = 2;};//Now clearly see this it updates ' x ' from params - } - the return function() { - varx = 3;//Now clearly see the this ' x ' is the from inner scope - y (); - Console.log (x); +}.apply ( This, arguments); -}
The reason that you need to define a parameter scope is that the default value of the function type, regardless of whether it is executed outside the scope or within the scope of the function, can cause problems.
Let's take a look at what happens if it's on the scope inside the function,
1 var x = 1 2 function foo (y = function () {return x; }) {// capture ' x ' 4 var x = 2; 5 return Y (); 6 7 8 foo (); // correctly 1, not 2
If function () {return x;} is executed within the scope of the function, then x in it captures the variable x inside the function (because the X in the internal scope is defined during the static parsing of Vo), but clearly, in terms of understanding, The X in the function should correspond to an external x instead of an inner one (unless a variable of the same name is also defined in the parameter, and then overrides the external variable with the same name). As a result, the main reason for not sharing the parameter scope and the function's inner scope is that the variable with the same name in the inner scope of the function should not affect the value of the variable with the same name that is bound in the parameter closure.
What if it was placed on an external scope,
1 var x = 1 2 function foo (y, z = function () {return x + y; }) {// can see ' x ' and ' y ' 4 var x = 3; 5 return Z (); 6 7 8 foo (1); //
This is where the problem becomes, function () {return x + y;} Since this function is on an external scope, there is no way to access the parameters of the intrinsic function, that is, the value of Y is not accessible, because Y is not defined on an external scope.
That is the "conditional" intermediate scope, that is, when the function does not define the default value of the parameter, it is not created in the middle scope of the parameter, at this time, the parameter binding is shared with the internal scope of the function, and in the ES5 mode of the same way.
This implementation is a compatibility of the way in which the default values of the parameters of the ES5 are manually implemented, allowing the variables in the function arguments to be accessed and modified inside the function and placed in the same scope.
The basic content is these, this part of the content is not much, but still can see a lot of language design ideas and the old version of the compatibility considerations. Write their own writing is the core of the content has been translated, but some of the details of the problem, but also can not be re-considered to clarify the clue.
Then plan to look at the parts of Lexical environments,
http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environments-common-theory/#environment-frames-model
Before probably looked at but not enough depth of understanding, a lot of the definition of the name and other feelings more around, it seems that the semantics of this thing is to rely on the semantics of the set.
So far.
ES6: Parameter default values and intermediate fields