JS变量提升,词法解析,重复声明会怎样?
2023-09-28 17:03:30
变量提升,相信大家都不陌生。在JS中,变量和函数会被提升到当前作用域的顶部。这意味着,无论你在代码中声明变量或函数的位置,它们都会被提升到作用域的顶部。
那么,如果变量或函数在代码中重复声明或定义会怎样?
变量提升
首先,让我们先回顾一下变量提升的概念。当浏览器解析代码时,它会先创建一个称为词法环境(Lexical Environment)的对象。词法环境包含了当前作用域中所有声明的变量和函数。当浏览器解析到一个变量声明语句时,它会将该变量添加到词法环境中。如果该变量之前已经被声明过,那么浏览器会忽略它。
例如,以下代码:
var x = 10;
var x = 20;
console.log(x); // 输出:20
在执行时,浏览器会先将x提升到当前作用域的顶部,然后将它赋值为10。当浏览器遇到第二个x声明时,它会忽略它,因为x已经被声明过。因此,console.log(x)会输出20。
词法解析
词法解析是编译器或解释器在编译或解释程序代码时,将源代码转换为词法单元(Token)的过程。词法单元是组成源代码的基本单位,例如、标识符、运算符、常量等。词法解析器会将源代码中的每个词法单元识别并提取出来,并生成一个词法单元流。
在JS中,词法解析器会先将源代码中的所有词法单元识别并提取出来,然后生成一个词法单元流。接下来,解释器会根据词法单元流生成抽象语法树(Abstract Syntax Tree,AST)。AST是一棵树状结构,其中每个节点代表一个语法元素。解释器会根据AST生成字节码或机器码,然后执行字节码或机器码。
词法解析和词法环境的创建是JS解释器执行代码的第一个步骤。这两个步骤对于JS的执行至关重要。
重复声明
那么,如果我们在代码中重复声明一个变量或函数会怎样?
对于变量,如果我们重复声明一个已经声明过的变量,那么浏览器会忽略它。例如,以下代码:
var x = 10;
var x = 20;
console.log(x); // 输出:20
在执行时,浏览器会先将x提升到当前作用域的顶部,然后将它赋值为10。当浏览器遇到第二个x声明时,它会忽略它,因为x已经被声明过。因此,console.log(x)会输出20。
对于函数,如果我们重复声明一个已经声明过的函数,那么浏览器会报错。例如,以下代码:
function f() {
console.log("hello");
}
function f() {
console.log("world");
}
f(); // 报错:Uncaught SyntaxError: Identifier 'f' has already been declared
在执行时,浏览器会先将f提升到当前作用域的顶部,然后将它赋值为第一个f函数。当浏览器遇到第二个f声明时,它会报错,因为f已经被声明过。
因此,在JS中,我们不能重复声明变量或函数。如果我们重复声明变量,那么浏览器会忽略它。如果我们重复声明函数,那么浏览器会报错。