Javascript JS是否将参数列表视为可以关闭的范围?
看看这个使用惰性表达式的简单代码:Javascript JS是否将参数列表视为可以关闭的范围?,javascript,ecmascript-6,Javascript,Ecmascript 6,看看这个使用惰性表达式的简单代码: var x=1; 函数foo(x=2,f=()=>x){ var x=5; console.log(f()) } foo()函数参数具有相同的作用域,可以使用前面相邻的参数值设置后一个参数。函数参数具有作用域 在第一个示例中,您分配了一个新的x变量,这就是为什么它不会覆盖: //全局x var x=1; 函数foo(x=2/*局部作用域x*/,f=()=>x/*局部作用域x绑定到新函数作用域*/){ /*新的本地范围x。如果删除“var”,这将覆盖本地范围
var x=1;
函数foo(x=2,f=()=>x){
var x=5;
console.log(f())
}
foo()
函数参数具有相同的作用域,可以使用前面相邻的参数值设置后一个参数。函数参数具有作用域
在第一个示例中,您分配了一个新的x
变量,这就是为什么它不会覆盖:
//全局x
var x=1;
函数foo(x=2/*局部作用域x*/,f=()=>x/*局部作用域x绑定到新函数作用域*/){
/*新的本地范围x。如果删除“var”,这将覆盖本地范围x*/
var x=5;
/*所有3个x都已访问*/
console.log(f(),x,window.x)
}
foo()
这是一个有趣的问题
最好参考Ecmascript 2017规范,以了解参数绑定机制的具体工作方式
定义一个函数时,有一个或两个函数在运行。根据参数是否具有默认值,环境记录设置的绑定会有所不同。如果参数具有默认值,则有2条环境记录正在运行。一个用于参数实例化,一个用于主体声明(如变量、内部函数等)
显然,当你喜欢的时候
function(x = 2, y = x){
...
}
在工作中有一个预分配功能,它必须有自己的上下文。如果是这样的话
function foo(x = 2, f = () => x) {
var x = 5;
console.log(f())
}
x
在定义函数参数时处于闭包状态
那么让我们看看它说什么
9.2.12函数声明安装(函数、参数列表)
为评估ECMAScript而建立执行上下文时
函数创建新的函数环境记录,并为其绑定
每个形式参数都在该环境记录中实例化。
函数体中的每个声明也被实例化。如果
函数的形式参数不包括任何默认值
初始值设定项,然后在同一文档中实例化主体声明
环境记录作为参数。如果是默认值参数
如果存在初始值设定项,则会为
机构声明。形式参数和函数初始化为
函数声明安装的一部分。所有其他绑定都是
在函数体求值期间初始化
此外,如果我们需要坐下来编写自己的JS引擎,我们还将详细介绍如何实现此功能的算法步骤27。a很有趣
27其他
a.注意,需要一个单独的环境记录,以确保由形式参数列表中的表达式创建的闭包不会
在函数体中具有声明的可见性
有趣。Babel当然会将其向下传输,以在函数体中移动声明,从而产生
5
,这将是一个bug。@NathanP。我知道这个例子不匹配。我指定了另一个例子我理解,而第一个(我不知道是否使用闭包)我不理解。什么是“惰性表达式”?第一个示例中的代码使用默认参数。删除var
将打印5
FWIW,如果在第一个示例中将var x=5
更改为let x=5
,则会出现错误,因为它已经声明过,因此要回答您的正式问题,否,参数列表没有自己的作用域。即使参数是一个直到以后才执行的函数?我对解释第二个示例不感兴趣。@CodingTrigue是。@RoyiNamir不确定你的意思?答案涉及第一个问题example@CodingIntrigue函数foo(x=2,y=x*10,z=()=>x*y){var x=5;alert(z())}foo()
,另请参见,Typescript显示5。。。。不知道为什么。我也不明白为什么删除var会改变结果。X处于关闭状态并被捕获,那么为什么它会被覆盖呢?请从三个部分来考虑。您的窗口范围在顶部,中间的参数范围和底部的函数范围。从较高范围继承的变量将被较低范围的var
取代,但如果不存在var
声明,我们将沿着链向上移动,直到找到一个或点击窗口。因此,在最低范围内添加变量声明只会影响在声明后使用该变量的方法。TypeScript将参数声明带入函数作用域,这解释了结果。如果它们有单独的作用域,那么我不明白为什么删除var会改变result@RoyiNamir如果您删除var
,则x
将指向在参数处声明的变量处的x
,在这种情况下,您将使用x=5对其重新赋值代码>指令。因此f
将打印5
。如果在函数体中用var
声明x
,它将覆盖参数中定义的x
,但函数将保留闭合值。当我们假设形式参数列表的范围包含函数体的范围时,使用let
绑定(而不是var
)声明x
)会导致错误,这确实很奇怪。我想函数体没有建立块作用域,而是一种不同的作用域,这不会影响let
绑定。@ftor这确实是一个很好的观点。它抛出一个“x”已声明为错误。我理解let
的块作用域只允许函数体,这与参数级声明的作用域与默认值(同时具有相同标识符的两个变量)冲突。