你不知道的javascript之变量声明和函数提升

it2023-02-01  48

最近重温了《你不知道的Javascript》这本书,看到自己做的笔记和标记,感慨良多,仿佛回到了半年前刚看这本书时的震撼和激动,因为这本书让我了解到了js的诸多原理。

虽说已经学习js两三年了,也跟老师做过项目,做过课程设计,参加过中国大学生计算机设计大赛,暑假在虎牙实习,本以为自己的js水平已经可圈可点,但自从看了这本书后,才发现自己不过是了解了js庞大的知识体系中的冰山一角。所以我决定把我了解到的一些js原理的东西写下来,希望能帮到有缘人。

接下来要讲述的是js中的变量声明提升和函数声明提升,后续还会继续写闭包、this指向、对象、原型等。

变量声明提升

        考察下面两段代码,分别输出什么?

        

        

        第一段代码的打印a的值为2,这很好理解,因为变量声明提升,var a;这段代码会提升到作用域的顶层,也就是提升到赋值语句a = 2的前面,所以整段代码的可以改写为var a = 2;console.log(a);输出的a的值自然为2。

       那么第二段的代码输出a的值是多少呢?是输出2,还是会抛出 ReferenceError 异常(变量 a 在使用前没有先进行声明)?然而两种答案都不是,正确的答案的输出undefined。下面给出解释:

       引用书中的一句话:“你看到 var a = 2; 时,可能会认为这是一个声明。但 JavaScript 实际上会将其看成两个 声明:var a; 和 a = 2;。第一个定义声明是在编译阶段进行的。第二个赋值声明会被留在 原地等待执行阶段。”也就是说,第二段代码等同于如下代码:

        var a;          console.log( a );          a = 2;

       以上代码表示: a变量被声明了,但是还未赋值就使用它,输出的值自然是undefined。对于变量声明提升,我们需要记住一句话:只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。

函数声明提升

对于函数声明我们只需要记住一句话:函数声明会被提升,但是函数表达式却不会被提升。

考察下面两段代码:

        

       上面这段代码可以正常运行,因为函数声明会被提升。

        

        上面这段代码会报错,因为函数表达式不会被提升,所以在语句foo()处,foo的值为undefined,而foo() 由于对 undefined 值进行函数调用而导致非法操作, 因此抛出 TypeError 异常。

 变量声明提升和函数声明提升

        上面分别讲了变量声明提升和函数声明提升的场景,那么当它们两者同时出现的时候,哪个声明的优先级更高呢?

        我们来考察一下下面的代码:

        

        上面代码声明了一个同名的foo,一个变量声明,一个是函数声明,那么在函数调用语句foo();处输出的结果是什么呢?答案是1,也就是函数声明foo中的语句console.log(1)语句的执行结果,看到这个结果,你们明白了哪个声明的优先级更高了吗?

        当变量声明和函数声明同时出现时,我们只需要记住:函数在js中是一等公民,即数声明和变量声明都会被提升,但是函数会首先被提升,然后才是变量。

        最后,给大家留下一个题,下面代码的输出结果是什么呢?期待在大家的留言。

 

最新回复(0)