问题
I'm a bit confused about how scope & variable assignment within a function seems to change when assigning a default parameter value for that function.
For example, when this function has a default value assigned to parameter i, the output array variable appears to be block-scoped when inspected with Chrome Dev Console,:
function steps(n, i = 40) {
var output = [n];
}
steps(10, 20);
However, by removing the default parameter value for i, the output array variable is scoped locally:
function steps(n, i) {
var output = [n];
}
steps(10, 20);
Why does assigning a default value to parameter i affect the scope of the output array variable?
I was initially made aware of this shift in function scope by attempting to run the following segment of code through pythontutor.com's live programming environment for Javascript. Even though the code executes as expected within an IDE, it fails to run due to scope issues on pythontutor:
function steps(n, i = 1) {
// declare base case
if (n === 0)
return;
var output = [];
print(i, "#");
print(n - 1, " ");
console.log(output.join(""));
// make recursive call
steps(n - 1, i + 1);
function print(num, char) {
for (let j = 0; j < num; j++) {
output.push(`${char}`);
}
}
}
steps(3);
The pythontutor processor halts execution three steps in, at the invocation of print() just after declaring the output variable. Pythontutor.com will, however, execute the code as expected if I declare the output variable globally first:
var output = [];
function steps(n, i = 1) {
// declare base case
if (n === 0)
return;
output = [];
print(i, "#");
print(n - 1, " ");
console.log(output.join(""));
// make recursive call
steps(n - 1, i + 1);
function print(num, char) {
for (let j = 0; j < num; j++) {
output.push(`${char}`);
}
}
}
steps(3);
回答1:
It's because default initialisers run in their own scope. Only if there are none, the body code is evaluated in the top function scope. It would only make a difference if you put a function expression in a default initaliser, which may close over the other parameters but does not have access to the variables that will be declared in the body.
Basically it's the difference between
function steps() {
var n = arguments[0],
i = arguments[1];
var output = [n];
}
and
function steps() {
var n = arguments[0],
i = arguments.length > 0 ? arguments[1] : 40;
(() => {
var output = [n];
}());
}
来源:https://stackoverflow.com/questions/48331336/js-default-function-parameter-values-and-scope