铺垫:
我们要知道编译器是在代码执行前进行编译的,编译相当于JS在 拿到“考卷(也就是代码)”先进行的审题,获取所有变量声明(var a)和函数声明以及全部函数体(function abc(){这里函数体全部内容都获取到})就是在这个阶段;
审完题也就是编译器编译完成之后需要 由JS引擎来做题(执行);
所以 编译器负责审题(编译代码),JS引擎负责做题(执行代码)
名词解释:当前作用域:作用域分为全局和局部,局部作用域一般指函数内
我们再来说说变量声明在js编译器和引擎眼里的情况:
var a = 2;
变量的声明分为如下阶段:
①JS拿到代码;
扫描二维码关注公众号,回复:
3750534 查看本文章
②编译器审题:在当前作用域只声明一个变量(var a)
③编译器编译其他代码;
③JS引擎做题:审完题(编译完成之后),做到哪个位置(看到哪个赋值)就给之前声明的变量赋上值(a = 2)
例如:
var v='Hello World'; function foo(){ alert(v); }; foo()
这里很就是一般情况,会弹出“Hello Worhld”
而:
var v='Hello World'; function foo(){ alert(v); var v = "GOGO" }; foo()
这个时候alert的是什么?
答案就是Undefined
为什么呢?
因为函数内(局部作用域内)在代码执行前的编译(审题),已经获得了var v的声明,并且在要求alert(v)的时候,还没有看到赋值,所以v的值是undefined
所以实际上是这样:
var v='Hello World'; function foo(){ var v; //编译期间获取到的声明 alert(v); v = "GOGO"; //JS引擎在代码执行到这一行,找到值以后才会赋值给v }; foo()
这个就是变量提升,
欢迎拍砖和拍砖,感谢!