4

我正在观看一个关于 javascript 范围的视频,它说就在浏览器解释 java 脚本代码之前,它实际上涉及一个快速编译步骤(可以说不完全是“编译”,因为它不涉及制作中间文件),它注册变量和各自范围内的函数声明。所以如果我写:

var a = 3;
function foo(){
var c = 2;
}

在评估上述表达式之前,这意味着忽略 RHS 部分,变量“a”和函数“foo”将在全局范围内注册,在“foo”范围内,变量“c”将被注册。在此编译步骤之后,将对表达式的值进行评估。

但是当我们写的时候会发生什么:

var a = function(){
var c;
}

编译步骤是否只是在全局范围内注册变量'a'并跳过函数声明和变量'c'声明,因为编译步骤应该跳过RHS部分并且评估表达式进入解释器部分?

4

1 回答 1

0

其实我后来想通了。是吊装。提升仅适用于变量和函数声明,不适用于函数表达式。事实证明,函数表达式中的函数及其局部变量被注册的唯一时间是当 java 脚本解释器运行时(编译后),因为编译步骤不会打扰它们,因为它们在 RHS 部分。这确保了在函数表达式的情况下,我们仅在其赋值之后调用它,并且解释器负责在全局范围内注册的函数,将其分配给 LHS 变量并声明其局部变量(var bar;):

var foo = function() {
  console.log(bar);
  var bar = 5;
};
foo();

仅当解释器到达此行时才创建此函数对象:

var foo = function abc() {

如果这是函数声明的情况,如下所示:

foo();

function foo() {
  console.log(bar);
  var bar = 5;
}

提升将确保在编译步骤中注册函数“foo”并在其范围内声明变量“bar”。

尽管如此,这两个程序都会给出相同的输出 - “未定义”。

于 2017-04-21T16:06:27.483 回答