> 文档中心 > 浅聊JS预处理,以及提升问题

浅聊JS预处理,以及提升问题

在这里插入图片描述

引导

我们都说 , JavaScript 是解释型语言 , 执行到哪一行就编译解释执行哪一行

那我们看下面这个代码

console.log(a)var a = 1

你觉得他打印出的是什么呢? 1 还是 报错 a is not defined
当然都不是,实际上打印 undefined
浅聊JS预处理,以及提升问题

实际上,它等同于下面这些代码

var aconsole.log(a)a = 1

那么说 JavaScript 是解释型语言就解释不通了。 因为明明先执行 console.log(a) 按理说,应该报错。

那么 JavaScript 是不是解释型语言呢?

JS 预处理

我觉得 , JavaScript 不能说是完全的解释型语言,因为上面的情况解释不通。也不是完全的编译型语言。因为它切切实实不会先编译成其他文件。我们知道 C 语言会编译成 .exe , Java 会编译成 .class .。JS 就我们编写的,保存的始终都是 .js

其实 Js 在执行前,是有先编译的。只不过是在代码开始执行前的一段很短很短的时间内完成。(实际编译成是什么,有几个步骤,如何保存编译结果在此不做讨论,因为我了解的也不多)

有人会把这个过程叫做 预处理

回到上面这个问题。如果 Javascript 在执行前会先编译(预处理) , 那么上面那个代码的结果就有的解释了。

提升

变量提升

我们把上面的情况叫做 变量提升
也就是 JS 在编译时 , 会把 var 的定义变量进行提升, 也就是提升到所有代码执行之前。
那么下面这个代码,你就能正确的回答出a 输出的值了

console.log(a)console.log('b')console.log(a)console.log('c')console.log(a)var a  = 1

没错,都是 undefined
你也可以知道,它相当于是这样子的

var a console.log(a)console.log('b')console.log(a)console.log('c')console.log(a)a  = 1

注意:

var 可以变量提升 , letconst 是不行的。可以自己去试试哦!

函数提升

看看它输出什么呢?

console.log(f)function f(){return 123}

可不是 undefined 也不是报错。
而是f f(){ return 123}
浅聊JS预处理,以及提升问题
这意味着,我们可以在定义函数前, 先执行这个函数。

f()  // 123function f(){console.log(123)}

函数的提示和变量的提升有所不同。函数的提升会把函数值也提升赋值
因此就可以先执行再定义。

注意

function 定义的函数可以提升 , 通过变量创建的函数和箭头函数是不会提升的。但如果是通过 var 定义的变量来保存函数,也会提升,但不会提升函数值。

console.log(h);  // undefinedvar h = function(){return 123}

提升优先级

这也可能是面试题的考点。
先看看这两个输出什么:

var a = 123function a(){return 321}console.log(a)function b(){return 456}var b = 654console.log(b)

你认为会输出什么呢?

答案是 123 , 654
也就是 var 变量被赋予的值。

这不能简单的用覆盖来解释

// 先var  a =  1// 然后     a = 2     //所以: a = 2

也不能简单的用提升来解释。

实际这个问题是这样子的。
因为函数的提升优先级比变量高。因此会先提升函数,同时提升函数值。然后又提升变量 ,但此时值还是函数的值。然后执行到变量赋值后,函数值就被替换成变量值了,也就是覆盖

也就是其实是这样子的:
原代码:

var a = 123function a(){return 321}console.log(a)

实际是:

functioon a(){return 123}var aa = 123console.log(a)

那么,到这里,你应该能知道下面输出的是什么了

console.log(d);  var d = 'ddd'function d(){    console.log('d()');}

是的,输出的是函数
在这里插入图片描述

强国军事网