场景
开始读es6的时候,一开始介绍的是let和const指令,文章中就提到一个概念 => 变量提升。原文是这样说的:let不像var那样会发生“变量提升”现象。对我这个菜鸟来说,what?什么是变量提升。经过一番度娘以后,有了个大概的概念和自己的理解。
理解
比较官方一点的解释这样的:JavaScript在工作时会先获取所有变量,然后再一行一行地执行代码。这就导致了所有变量声明的语句都会被提升到代码的最前面。这就是变量提升。
栗子
var a = 5; function fn(){ a = 3; console.log(a) var a; } fn()
很简单的一段代码,最终输出的是3。函数内的a覆盖了外面的变量a,var a;并没有刷新a的值,因为真正在运行时的顺序应该是这样的
var a = 5; function fn(){ var a; a = 3; console.log(a) } fn()
我们可以看到,写在下面的声明a的语句被提前到了函数的最上面,所以最后输出的是函数内部的变量a而不是外面的a = 5
var a = 5; function fn(){ console.log(a) var a = 3;; } fn()
在这里又会发生什么呢?我们看一下运行结果:
可能有人会说为什么打印的不是5呢?这就是变量提升的神奇之处,使用var声明的变量在运行时该声明语句会被放在当前当前作用域的最上面。这里又涉及到一个作用域的概念,暂时可以简单理解为一对大括号就是一个作用域。
所以上面的代码在运行时的顺序应该是这样的:var a = 5; function fn(){ var a; console.log(a) a = 3;; } fn()
变量提升只是把声明语句提升上去,而赋值语句是不会被提升的。明显可以看到在函数内部还是新创建了一个变量a,但是在打印前都没有给a赋值,所以最后打印出来的值是‘undefined’
函数
除了变量提升意外,函数也是存在这样的现象,我们来看一段代码
// 代码一 fn() function fn(){ console.log(0) } //代码二 fn() var fn = function() { console.log(0) }
直接看结果:
代码一运行正常,代码二就报错了。因为代码二的实际运行顺序其实这样的
var fn; fn(); fn = function() { console.log(0) }
很显然,执行fn();之前fn只是一个变量,以函数的方式调用变量肯定是错误的用法。
注意:es6提出的新指令let和const是不会发生变量提升现象的,所以在使用es6语法时,一定要先声明再调用。
到此,本人知道的有关JavaScript的变量提升方面的知识就只有这么多,如果有幸这篇文章被你看到了,相信你看完以后也会对这个知识点有个大概的了解了。如果觉得有什么地方说得不对的,欢迎指正。