JS: Default function parameter values and scope

感情迁移 提交于 2021-01-27 21:33:56

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!