你们好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新......前端
- github:https://github.com/Daotin/Web
- 微信公众号:Web前端之巅
- 博客园:http://www.cnblogs.com/lvonve/
在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。如今就让咱们一块儿进入 Web 前端学习的冒险之旅吧!git
先来看两个栗子,下面的两段代码分别输出什么?github
// 代码段1 function foo() { var a = 1; function a() {} console.log(a); } foo(); // 代码段2 function foo() { var a; function a() {} console.log(a); } foo();
答案是:代码段1打印的是1,代码段2打印的是 a() 函数。segmentfault
为何会这样呢?这就涉及到js中的变量提高和函数提高的具体过程了。微信
js是怎么建立变量的呢?函数
以下面的代码:学习
var a = 1; var b = 2;
js在解析上面的代码的时候,其实会按照下面的方式进行解析的:spa
var a; var b; a = 1; b = 2;
因此 js 并非在咱们定义一个变量的时候,声明完成以后当即赋值,而是把全部用到的变量所有声明以后,再到变量的定义的地方进行赋值,变量的声明的过程就是变量的提高。3d
因此咱们看下下面的栗子:code
function foo() { var a = 1; console.log(a); console.log(b); var b = 2; } foo();
上面的代码在js的眼中是这样解析的:
function foo() { var a; var b; a = 1; console.log(a); // 1 console.log(b); // undefined b = 2; } foo();
因此输出的 a 的值为1, b的值为 undefined。
变量在声明提高的时候,是所有提高到做用域的最前面,一个接着一个的。可是在变量赋值的时候就不是一个接着一个赋值了,而是赋值的位置在变量本来定义的位置。本来js定义变量的地方,在js运行到这里的时候,才会进行赋值操做,而没有运行到的变量,不会进行赋值操做。
因此变量的提高,提高的实际上是变量的声明,而不是变量的赋值。
函数的提高和变量的提高相似,都是提高到做用域的最开始的位置,只不过变量的提高是分两步的,第一步是变量声明的提高,第二步是变量的赋值。而函数的提高是直接将整个函数总体提高到做用域的最开始位置,至关于剪切过去的样子。
在做用域中,无论是变量仍是函数,都会提高到做用域最开始的位置,不一样的是,函数的提高后的位置是在变量提高后的位置以后的。
举个栗子:
下面的代码输出什么?
function foo() { console.log(a); var a = 1; console.log(a); function a() {} console.log(a); } foo();
上面的代码在js眼中是这样解析的:
function foo() { var a; function a() {} console.log(a); // a() a = 1; console.log(a); // 1 console.log(a); // 1 } foo();
因此从上面的栗子能够看到,变量的提高是在函数提高以前的,可是变量赋值的部分是在js原型到变量定义的位置才给变量赋值的,而函数提高是至关于直接剪切到最前面的。
咱们再看一个更加复杂一点的栗子:
function foo() { console.log(a); var a = 1; console.log(a); function a() {} console.log(a); console.log(b); var b = 2; console.log(b); function b() {} console.log(b); } foo();
js是这样解析的:
function foo() { var a; var b; function a() {} function b() {} console.log(a); // a() a = 1; console.log(a); // 1 console.log(a); // 1 console.log(b); // b() b = 2; console.log(b); // 2 console.log(b);// 2 } foo();
最后,注意:只有声明的变量和函数才会进行提高,隐式全局变量不会提高。
下面的栗子中,b不会进行变量提高。
function foo() { console.log(a); console.log(b); // 报错 b = 'aaa'; var a = 'bbb'; console.log(a); console.log(b); } foo();
js变量提高与函数提高的机制: http://www.javashuo.com/article/p-nudwgxqp-eg.html