一、什么是变量提升?var变量提升的底层原理是什么?
变量提升的定义:所有变量的声明语句都会被提升到代码头部,这就是变量提升。
原理:引擎在读取js代码的过程中,分为两步,专业来说代码运行是分为预处理和执行两个阶段。
①先解析代码,获取所有被声明的变量;
②然后再执行。
记住这下面这两句话,你就可以再任何情况下从容面对任何变量提升的问题。
1.变量提升只会提升变量名的声明,而不会提升变量的赋值初始化。
2.函数提升的优先级大于变量提升的优先级,即函数提升在变量提升之上。
例如:
console.log(a); var a =1;
以上语句并不会报错,只是提示undefined
。实际在js引擎中的运行过程是:
var a; console.log(a); a =1;
实际运行表示变量a已声明,但还未赋值。
但是变量提升只对var命令声明的变量有效,如果一个变量不是用var命令声明的,就不会发生变量提升。
console.log(aa); aa =1; 或者 console.log(aa); let aa =1;
以上代码将会报错:ReferenceError: aa is not defined
。
注意:这里有两句话:1、并不会报错,只是提示undefined。2、报错:
ReferenceError: aa is not defined
。
那么Javascript中undefined和not defined有什么区别?看本系列第二个知识点解答
下面是关于函数提升的内容:
补充:js里的function
也可看做变量,也存在变量提升情况
a(); function a(){ console.log(1); };
没毛病,输出1。表面上,上面代码好像在声明之前就调用了函数a
。但是实际在js引擎中,由于“变量提升”,函数a
定义部分被提升到了代码头部,也就是在调用之前已经声明了。
但是!!如果采用赋值语句定义函数,JavaScript就会报错:
a(); var a = function(){ console.log(1); }; // TypeError: a is not a function
因为js引擎把变量声明提升,此时,a就是一个变量,而并不是一个function,以下是js引擎实际运行代码:
var a; a(); a = function(){ console.log(1); };
但是,如果把上面代码调换下位置,输出结果就不一样了
var a = function(){ console.log(1); }; a(); // 1
以上变量提升的问题已基本描述清楚。请看下面一道面试题:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>变量提升</title> 5 <meta name="keywords" content="keyword1,keyword2,keyword3"> 6 <meta name="description" content="this is my page"> 7 <meta name="content-type" content="text/html; charset=UTF-8"> 8 </head> 9 <body> 10 <script type="text/javascript"> 11 console.log(foo); 12 foo(); 13 var foo=10; 14 foo(); 15 console.log(foo); 16 function foo(){ 17 var a; 18 console.log(a); 19 a=12; 20 console.log(a); 21 } 22 console.log(foo) 23 </script> 24 </body> 25 </html>
猜猜输出会是啥?