考慮下面的代碼:瀏覽器
var myvar = 'my value';
alert(myvar); // my value
Okay, 固然,彈出的結果確定是"my value"
,可是,跟着我,讓我下面建立個方法,彈出相同的值:wordpress
var myvar = 'my value';
(function() {
alert(myvar); // my value })();
好吧,好吧,仍然很明顯,我知道。如今,讓咱們加點猛的調料,在匿名函數內部建立一個同名的局部變量。函數
var myvar = 'my value';
(function() {
alert(myvar); // undefined var myvar = 'local value';
})();
哈啊?爲何彈出的是undefined
呢?即便咱們聲明瞭一個新的變量,可是它在alert的下面啊,照理說應該不會有影響啊,是嗎?仍是?spa
在當前的做用域內,不管在哪裏變量聲明,在幕後,其都在頂部被「預解析」了。不過,僅聲明被「預解析」。該變量即便初始化,其當前的值,在做用域的頂部,也會被設置成undefined
。翻譯
恩,如今讓咱們好好的破譯下這個「聲明」和「初始化」,以var joe = 'plumber';
爲模特吧。code
聲明(Declaration)ip
var joe; // the declaration
初始化(Initialization)作用域
joe = 'plumber'; // the initialization
如今,咱們知道了這些術語的意思,就能夠更好的理解到底背地裏都幹了些什麼勾當,請看下面的僞函數:字符串
(function() { var a = 'a'; // 一行代碼 var b = 'b'; // 更多行的代碼 var c= 'c'; // antipattern // 最後一行腳本 })();
需注意,上面的這作法是不太好的。可是,先無論這個,在程序的背後,這個變量聲明不管在函數做用域的什麼地方,都被置頂解析了,就像下面這樣:get
(function() { var a, b, c; // variables declared a = 'a'; // 一行代碼 b = 'b'; // initialized // 更多行的代碼 c= 'c'; // initialized // 最後一行腳本 })();
如今回到使人疑惑的undefined
代碼段
var myvar = 'my value';
(function() {
alert(myvar); // undefined
var myvar = 'local value';
})();
如今應該比較容易理解爲什麼myvar
彈出的是undefined
了。正如上面學到了,當咱們聲明myvar
變量的時候,其自動的在函數做用域的頂部(在alert的前面)進行「解析」了。結果,在alert的時候時的變量尚未被聲明。然而,因爲初始化的值是不會做用域置頂的,因此,最後alert的值是undefined
。
//zxx:以上爲翻譯全文
上面彈出undefined
的代碼實際上就等效於下面的代碼:
var myvar = 'my value';
(function() {
var myvar;
alert(myvar); // undefined
myvar = 'local value';
})();
JavaScript的預解析不只適用於變量,彷佛也適用於函數,你有興趣能夠看下下面這個例子:
g = function() { return false; };
(function() {
if(g()) {
function g() { return true; }
alert("in"); //IE6~8,Chrome,Safari,Opera瀏覽器執行 }
})();
在非Firefox瀏覽器下,會彈出字符串"in"
的,固然,這裏的重點不是哪一個瀏覽器執不執行,因此不考慮Firefox的問題,function g() { return true; }
含函數做用域頂部(在if的前面)「預解析」,因此,if語句能夠執行。
本文涉及到JavaScript一些運行機制,自己資質也有限,因此文章可能有翻譯或是表述不許確的地方,還望竭盡全力的指正,不甚感謝。
原創文章,轉載請註明來自張鑫旭-鑫空間-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=1162