作者:呆保保_369 | 来源:互联网 | 2023-10-10 14:48
http://www.ecma-international...
中提到:
If the function’s formal parameters do not include any default value initializers then the body declarations are instantiated in the same Environment Record as the parameters. If default value parameter initializers exist, a second Environment Record is created for the body declarations. Formal parameters and functions are initialized as part of FunctionDeclarationInstantiation. All other bindings are initialized during evaluation of the function body.
ES6中参数的默认值会产生一个参数作用域,并且该作用域与函数作用域是独立的。但是在查阅了很多博客和相关例子之后,有两个问题不太明白:
一.
1 2 3 4 5 6
| function f1 ( x = 2, f = function () { x=3; } ){
let x = 5;
f( );
console.log( x );
}
f1(); |
参数作用域和函数体作用域是独立的、不共享的。既然如此,为什么上面的例子会报错,说x已经存在呢?如果在同一个作用域内用let重复声明一个变量,确实会报错,但是无法理解为什么这里不是同一个作用域也会报错。
二.
参数作用域和函数体作用域是什么关系?查阅了很多资料也没找到这两者具体的关系,但是用“父子关系”来解释很多例子基本都是行得通的,所以假设参数作用域包含了函数体作用域。但是,这样的话又无法解释下面这段代码:
1 2 3 4 5 6
| function f1 ( x = 2, f = function () { x=3; } ){
var x;
f( );
console.log( x );
}
f1(); // 2 |
根据作用域链查找的规则,在准备打印x的时候,其实函数体内已经找得到x了,只是这个x未赋值,所以这时候理应就是打印这个未赋值的x。但是最后输出的结果是2,这应该怎么理解呢?难道这里访问到的是参数作用域中的x吗?那么函数体内的x在作用域链查询的时候为什么看起来好像被忽略了?
以上两个问题没有想清楚,希望可以得到回答,或者说是提供思考和验证的方向。谢谢。