function foo(a,b){
return a + b;
}
foo(1,2);
函数参数是否被提升?
函数执行上下文创建阶段的variableEnvirnoment是否如下所示:
VE = {
{ 0 : undefined , 1: undefined, length: 2 },
{a : undefined, b: undefined},
outer: refToGlobalLE
}发布于 2020-05-09 22:51:17
是的,参数已提升。
调用函数时,函数体中的每个声明(var、let、const和函数声明)都在该执行上下文的环境记录中实例化。每个形参也以相同的方式添加到环境记录中(9.2.10 21.c.i和9.2.10 28.e.i.2)。整个过程在规范的section 9.2.10中进行了描述。
形参和函数声明都是在称为FunctionDeclarationInstantiation的抽象操作期间初始化的(注意:不是“实例化的”)。所有其他绑定都是在函数体计算期间初始化的。
这意味着形参绑定被添加到相同的逻辑位置,与函数体声明的方式相同。var、let、const和函数声明(顺便提一下,all of which are hoisted)。这意味着形式参数绑定以与函数声明相同的方式初始化(即,它们的相应值被设置在函数的顶部)。
提升是实例化标识符绑定的时间和位置的函数。形参绑定的实例化(和初始化)方式与函数声明相同。我们知道函数声明是提升的,因此参数绑定也是提升的。QED.
在ES2015之前,据我所知,这种提升是不可见的,因为函数参数已经位于函数的最顶端。但是,在ES2015中添加了参数默认值初始化器语法,使提升在用户空间中可见。
如果未提升形参,则以下代码不会抛出"Uncaught ReferenceError: Cannot access 'x' before initialization",因为z的默认参数值将引用外部x:
var x = 'global'
(function(y, z = x, x) {}()) // "Uncaught ReferenceError: Cannot access 'x' before initialization"
你的评论说“假设参数被提升,x将被初始化为"undefined",因此错误不会发生,因为x已经被初始化了”。您的意思是,提升也可以用来解释没有错误。这是真的,,但这并不意味着如果观察到错误,提升就不可能发生。实际上,我们可以看到正在发生提升,因为正如在错误消息中指定的那样,z = x中的x被认为引用了稍后在程序文本中声明的形参x。唯一可能做到这一点的方法是已经发生了提升。
发布于 2020-05-09 22:21:00
不能,JavaScript中没有提升函数参数。
function foo(a,b){
return a + b;
}
foo(1,2);为了简要地解释整个过程,我想解释一下函数本身是如何调用的。因此,由于您所说的是变量环境(在本例中是全局执行上下文),基本上逐行执行代码的JavaScript线程会将函数定义代码作为foo变量的值存储在内存中,而不会执行它(它只是按原样保存定义)。它移动到下一个执行行,这行显然对foo函数定义进行了函数调用(使用圆括号)。
现在,当该函数被调用foo(1,2)时,首先在该foo函数的全局执行中创建一个新的执行上下文。你可以把它想象成一个抽象化的盒子。参数1和2与函数的'a‘和'b’参数映射为foo执行上下文中的变量,而不是全局执行上下文。然后,该函数通过调用堆栈将a+b的值返回到全局执行上下文。
好的,为了检查这一点,如果你只是调用函数,然后像下面这样定义它
foo(1,2);
function foo(a,b){
return a + b;
}您可能会得到一个错误,因为foo函数定义不存在于全局执行上下文中,并且基本上会导致引用错误。
现在,谈谈参数本身,不管它们是否被提升。那就不!它们是在调用函数并创建新的执行上下文时自己创建的。这些变量是函数的块作用域,对外部/全局执行上下文不可见。因此,当函数返回给被调用者时,它内部的变量只是垃圾回收。
希望这回答了你的问题。
https://stackoverflow.com/questions/61697774
复制相似问题