你們好,這裏是「 從零開始學 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