JavaScript声明提前介绍和示例解析

2021年3月12日15:17:39 发表评论 686 次浏览

JavaScript中, 提升是在代码执行之前将所有声明移到作用域顶部的默认行为。基本上, 它给我们带来的好处是, 无论在何处声明函数和变量, 无论它们的作用域是全局的还是局部的, 它们都将移至其作用域的顶部。

它使我们能够在甚至将其写入代码之前调用函数。

注意:JavaScript仅提升声明, 而不提升初始化。

让我们了解这到底是什么:

以下是变量声明和初始化的顺序。

声明–>初始化/赋值–>使用

// Variable lifecycle
let a;        // Declaration
a = 100;      // Assignment
console.log(a);  // Usage

但是, 由于JavaScript允许我们同时声明和初始化变量, 所以这是最常用的模式:

let a = 100;

注意:永远记住, JavaScript在后台首先声明变量, 然后对其进行初始化。最好在执行任何代码之前先处理变量声明。

但是, 在javascript中, 未声明的变量在执行分配它们的代码之前不存在。因此, 在执行赋值时, 将值分配给未声明的变量会隐式将其创建为全局变量。这意味着所有未声明的变量都是全局变量。

// hoisting
function codeHoist(){
     a = 10;
     let b = 50;
}
codeHoist();
  
console.log(a); // 10
console.log(b); // ReferenceError : b is not defined

输出如下:

JavaScript |声明提前1

说明:在上面的代码示例中, 我们创建了一个名为codeHoist()的函数, 其中有一个未使用let / var / const声明的变量和一个let变量b。未声明的变量由javascript分配了全局作用域, 因此我们可以在函数外部打印它, 但是在变量b的情况下, 作用域是受限的, 并且在外部不可用, 并且我们得到ReferenceError。

注意:ReferenceError和未定义错误之间有区别。当我们有一个未定义或明确定义为未定义类型的变量时, 将发生未定义错误。尝试访问以前未声明的变量时, 抛出ReferenceError。

ES5

当我们谈论ES5时, 我们想到的变量是var。与let / const相比, 使用var进行提升有些不同。让我们利用var来看看提升的工作原理:

// var code (global)
console.log(name); // undefined
var name = 'Mukul Latiyan' ;

输出如下:

JavaScript |声明提前2

说明:

在上面的代码中, 我们尝试控制台变量名, 该变量名稍后声明并分配, 然后使用它, 编译器给我们

未定义

我们没有想到, 因为我们应该得到

ReferenceError

因为我们甚至在声明名称之前都在尝试使用名称变量。

但是解释器对此有不同的看法, 上面的代码如下所示:

//how interpreter sees the above code
var name;
console.log(name); // undefined
name = 'Mukul Latiyan' ;

输出如下:

JavaScript |声明提前3
函数范围变量

让我们看看如何提升函数范围变量。

//function scoped
function fun(){
     console.log(name);
     var name = 'Mukul Latiyan' ; 
}
fun(); // undefined

输出如下:

JavaScript |声明提前4

与在全局声明变量的代码相比, 这里没有什么区别, 因为解释器看到的代码是:

//function scoped
function fun(){
     var name;
     console.log(name);
     name = 'Mukul Latiyan' ;
}
fun(); // undefined

输出如下:

JavaScript |声明提前5

为了避免这种陷阱, 我们可以确保

在使用之前, 同时声明和分配变量

。像这样:

//in order to avoid it 
function fun(){
     var name = 'Mukul Latiyan' ;
     console.log(name); // Mukul Latiyan
}
fun();

输出如下:

JavaScript |声明提前6

ES6

我们知道, 用let关键字声明的变量是块作用域作用域, 而不是函数作用域作用域, 因此, 在起吊方面没有任何问题。

例子:

//let example(global)
console.log(name);
let name= 'Mukul Latiyan' ; // ReferencError: name is not defined

输出如下:

JavaScript |声明提前7

像以前一样, 对于var关键字, 我们希望日志的输出未定义。但是, 由于es6 let不会使用未声明的变量来帮助我们, 因此解释器会明确吐出Reference错误。这样可以确保我们始终

宣布

我们的变量优先。

const

举升时的行为与let相似。


木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: