ES6 形参的陷阱

先看代码:

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

问题:写出上述代码的执行时的打印结果?

这是昨天(2017-2-27)面试一家公司时遇到的问题,其实一开始我的想法是,执行s后,y开始执行的时候,就近原则,y中修改的应该是s内部的x,但是很明显是错的。

以前我错误的认为是作用域链的原因:

原因也很简单,就是定义函数时作用域链就已经形成了,而不是执行时生成的,执行时只是在作用域链上添加了一个保存他局部变量的对象,仅此而已。
上述调用s时,相当于 s( , function (){ x = 2 });所以形参是在函数外面定义的,因此y能访问的变量只能是全局的x。

最近(2025.5.21),有契机又在MDN上看了函数关于默认参数的定义才发现,其实默认参数的作用域才是关键:

The default parameter initializers live in their own scope, which is a parent of the scope created for the function body.

函数的默认值初始化的时候,是有在其自己的定义域里的。而这个作用域则是创建其函数体的地方

因此,y = function (){ x = 2 }执行时,相当于是在函数体外边执行的, 故而能访问到的x只能是s函数外边的x。

记坑完毕!

(关于原型链可以参考我的博文: 闭包)

posted @ 2018-02-28 08:59  子龙_子龙  阅读(12)  评论(0)    收藏  举报