ES6 参数默认值为函数,并在内部进行变量赋值

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

foo() // 3
x // 1

如果y赋值的函数是外部定义的话,最后的全局x为什么是 1
如果y赋值的函数是内部定义的话,foo()为什么会打印 3

阅读 2.6k
3 个回答

嗨,你的观察是正确的。这个作用域既不是“外”也不是“内”,而是夹在中间的作用域,这是为了防止默认参数被函数内部的变量污染。

题主你需要好好了解一下 ES6 的函数参数默认值。推荐一本书:《深入理解ES6》

在 ES6 里,参数默认值等效于直接展开:

function foo(x, y = 0) {....}
// =
function foo(x, y) {
  if (y === undefined) { y = 0 }
  ....
}

所以你的代码就等效于:

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

foo() // 3
x // 1

因为你在函数内部使用了 var x = 2;,所以 y() 操作的实际是闭包内部的 x,所以不会影响到闭包外面的 x

代码很有意思,不过实际项目中用到的可能不会太多。
其次 这不就是个闭包了么。
正如楼上提到的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进