咱們知道JS代碼在執行以前,會作一系列的事情,其中就包括變量提高,本來覺得把變量提高搞懂的我(由於這兩天一直在研究變量提高,自我感受已經很良好了,哈哈哈),拿到了一道打臉的題。固然了,拿給身邊的程序員朋友們,作對的也......廢話很少說,一塊兒來看下這道題吧。程序員
var a = 0;
if (true) {
a = 1;
function a() {};
a = 21;
console.log(a)
}
console.log(a);
複製代碼
答案:21 1web
首先說使用var
聲明的變量,只要那個變量是使用var
聲明的,那麼在變量提高階段要作的事情只有一個,就是去聲明這個變量。瀏覽器
一道簡單的題目看懂var
的變量提高編輯器
console.log(a);
var a = 1;
console.log(a);
複製代碼
console.log(a);
由於此時已經有a這個變量了,只不過沒有賦值,所以輸出undefined
var a = 1;
給變量a進行賦值爲1
console.log(a);
這時候再輸出a的值,就是上面的賦值結果1
控制檯查看輸出結果 函數
咱們知道使用let和const聲明的變量沒有變量提高,只有當代碼走到那一行纔會去執行聲明等操做;學習
在變量提高階段function會聲明+定義,這裏須要提到的一個點就是,重複的定義,會以最後一個指向的堆內存爲主。ui
下面使用一段代碼來解釋這句話的意思:spa
fn();
function fn() {console.log(1)};
fn();
function fn() {console.log(2)};
fn();
var fn = function () {console.log(3)};
fn();
function fn() {console.log(4)};
fn();
function fn() {console.log(5)};
複製代碼
var fn = function () {console.log(3)};
這句話在變量提高階段作的事情只是var了一個fn,右邊的並無執行;code
這道題能夠認真的思考下,能夠很好的理解變量提高和函數。orm
當function fn(){...}
沒有在if/for等任何大括號內的時候,它會聲明+定義,即:
但若是把上面的這句話放在if/for
這樣的大括號內的時候,就變成下面這樣的過程了:
function fn(){...}
的時候,它會去把全局中的fn修改一下,修改成堆中fn的值。修改完以後,後面對fn的操做又和全局的fn沒任何關係
這道題就是利用上面的所說到function(2)的變量提高狀況。即當在if/for中存在函數,而且條件成立,那麼這個函數就變爲私有,直到遇到function fn(){...}
的時候纔會去操做全局的fn,其它狀況操做的fn都是私有的。
下面是這道題的圖解過程
{
function foo(){}
foo=1;
}
console.log(foo);
複製代碼
{
function foo(){}
foo=1;
function foo(){}
}
console.log(foo);
複製代碼
{
function foo(){}
foo=1;
function foo(){}
foo=2;
}
console.log(foo);
複製代碼
這也是瀏覽器爲了解決新老版本改善的function的變量提高機制,能夠看出也是在一步步的完善,所以咱們也要不斷的學習,才能夠跟上互聯網的快速發展。