在JavaScript中,提升是在代码执行之前移动作用域顶部所有声明的默认行为。基本上,它为我们提供了一个优势,即无论函数和变量在哪里声明,它们都会被移动到其作用域的顶部,无论其作用域是全局的还是局部的。
它允许我们在编写代码之前调用函数。
注: JavaScript只提升声明,不提升初始化。
JavaScript在执行之前为程序中定义的所有变量和函数分配内存。
让我们了解这到底是什么: 下面是变量声明和初始化的顺序。
声明–>初始化/分配–>使用
// Variable lifecyclelet a; // Declarationa = 100; // Assignmentconsole.log(a); // Usage
然而,由于JavaScript允许我们同时声明和初始化变量,这是最常用的模式:
let a = 100;
注: 始终记住,在后台,Javascript首先声明变量,然后初始化它们。知道变量声明是在执行任何代码之前处理的也是一件好事。
然而,在javascript中,未声明的变量在执行分配它们的代码之前是不存在的。因此,将值赋给未声明的变量会在执行赋值时隐式地将其创建为全局变量。这意味着所有未声明的变量都是全局变量。
Javascript
// hoisting function codeHoist(){ a = 10; let b = 50; } codeHoist(); console.log(a); // 10 console.log(b); // ReferenceError : b is not defined |
输出:
说明: 在上面的代码示例中,我们创建了一个名为CodeHigh()的函数,其中有一个未使用let/var/const声明的变量和一个let变量b。未声明的变量由javascript分配全局范围,因此我们可以在函数外部打印它,但如果是变量b,范围受到限制,在外部不可用,我们会得到一个ReferenceError。
注: 引用错误和未定义错误之间有区别。如果变量未定义或显式定义为类型未定义,则会发生未定义错误。尝试访问以前未声明的变量时引发ReferenceError。
ES5
当我们谈论ES5时,我们脑海中浮现的变量是var。与let/const相比,var的提升有些不同。让我们利用var,看看提升是如何工作的:
Javascript
// var code (global) console.log(name); // undefined var name = 'Mukul Latiyan' ; |
输出:
说明: 在上面的代码中,我们试图控制变量名,该变量名是在使用它之后声明和分配的,编译器给了我们 未定义 这是我们没有预料到的 引用错误 因为我们甚至在声明之前就试图使用name变量。
但解释器的看法不同,上面的代码是这样的:
Javascript
//how interpreter sees the above code var name; console.log(name); // undefined name = 'Mukul Latiyan' ; |
输出:
函数作用域变量
让我们看看函数作用域变量是如何提升的。
Javascript
//function scoped function fun(){ console.log(name); var name = 'Mukul Latiyan' ; } fun(); // undefined |
输出:
与全局声明变量的代码相比,这里没有区别,因为解释器看到的代码是:
Javascript
//function scoped function fun(){ var name; console.log(name); name = 'Mukul Latiyan' ; } fun(); // undefined |
输出:
为了避免这个陷阱,我们可以确保 同时声明并分配变量, 使用前 .像这样:
Javascript
//in order to avoid it function fun(){ var name = 'Mukul Latiyan' ; console.log(name); // Mukul Latiyan } fun(); |
输出:
ES6
允许 我们知道,用let关键字声明的变量是块范围的,而不是函数范围的,因此在提升方面没有任何问题。
例子:
Javascript
//let example(global) console.log(name); let name= 'Mukul Latiyan' ; // ReferencError: name is not defined |
输出:
与前面一样,对于var关键字,我们希望日志的输出是未定义的。然而,由于es6 let不喜欢我们使用未声明的变量,解释器会显式地抛出一个引用错误。这确保了我们始终 声明 首先是我们的变量。
康斯特 在起吊时,其行为类似于let。