有沒有發現在寫代碼的時候,往往會遇到一些莫名其妙的錯誤,然后時間緊急不得不去網上查閱一些代碼。雖然要實現的功能解決了,但是看被拷貝的代碼好多真心看不懂,以后遇到諸如此類的問題,如果查閱不到這些代碼的話還是不會。所以今天給大分享一下內部原理的問題
###1.js編譯器編譯的幾條基本原則
>a.js預編譯:解釋函數聲明,忽略表達式;
>b.運行期間獲取變量會有底層向頂層依次查找,直到找到為止(華續以前已經分享過);
>c.變量的定義會被提前到body下,即所屬代碼最前面聲明;
>d.function func(){}這種聲明會被js編譯器解釋成var func = function(){}這種格式,是不是看了幾條規則,不知道我說的什么,沒關系,可能我總結的不好,看下面例子具體了解下
###2.自執行函數/閉包
>自執行函數,相信大家都接觸過,只是不知道而已,在此不給出具體文字定義。
>簡單解釋為:`類似(function(){...})()這種形式的代碼就叫做自執行函數,又稱閉包`他在js編譯器解析到時,直接被執行。一個簡單小例子: (function()
>{...})()可以被自執行,寫成function(){...}()可以被自執行嗎,答:不可以!
>如上面所說`規則a`,js預編譯時,先解釋函數聲明,因此function(){...}()前面的function(){...}在‘預編譯階段’已經被解釋成變量過了,js會跳過這段代碼,試圖去執行()里的內容,顯然不科學;
> 而(function(){...})()可以被自執行,因為它加了括號,它變成表達式了,js運行時會運行並對它求解得到一個返回值,而此處返回值是一個函數,故而遇到()便會執行
>###例1:
a=1;
console.info(a)
function b(){
console.info(a);
var a=10;
console.info(a);
};
b();
控制台打印:
1,undefined,10
你是不是預期是1,1,10,這里正是因為上面的`規則c`當js編譯器在執行這個b函數的時候,會把把它body里面的聲明變量提前到最前面進行聲明。如:var a=10; 編譯器先會在 body最前面進行var a 聲明。其實上面的代碼等同於下面的這段代碼:
a=1;
console.info(a)
function b(){
var a;
console.info(a);
a=10;
console.info(a);
};
b();
聲明a的時候還沒有值,故而打印undefined;再看下面一個例子...
###例2:
a=1;
function b(){
a=10;
return ;
function a(){};
};
b();
console.info(a);
控制台輸出:1
這里是因為上面的`規則b,d`在b函數中function a(){}實際是被編譯成var a = function(){},函數內部有一個a=10,外部有一個a=1,先找內部的a,找到不會向外找,而根據js 作用域,最終打印1;
###3.使用場景
有了上面的理論知識,可以解決曾經有人問我三元表達式后面怎么執行多條語句的問題,就是在后面寫自執行函數。當然,不排除有其它方法,代碼如下:
var a = 2>1?(function(){var c=2,d=1;return c+d;})():(function(){var c=2,d=1;return c-d;})();
console.info(a);
控制台打印:3
這種需求應該很少吧,我寧願寫個if,不過可以實現,呵呵...