首先來一個例子做實驗
function createD(){ var dir = { name: "d", ctrl: myCtrl, ctrl2: yourCtrl }; return dir; function myCtrl (){ console.log('my ctrl'); } var yourCtrl = function(){ console.log('your ctrl'); }; } var d = createD(); d.ctrl(); d.ctrl2();
可以猜一下輸出結果
//輸出:
d.ctrl(); //輸出: my ctrl
d.ctrl2(); //輸出: Uncaught TypeError: d.ctrl2 is not a function
首先以上例子中的寫法其實不太符合規范,變量及函數的定義最好都放在前邊。
var的function的聲明是不同的, var的聲明會讓變量聲明提升到作用域頂部,但是變量的賦值還是在原位, 所以變量賦值如果在return后,也不會執行。 而function聲明的話,會全部提升到頂部執行。
所以,createD() 里邊的 yourCtrl變量實際是undefined 還沒有來的及賦值即return掉了。
預編譯后的代碼會如下:
function createD(){ var dir = { name: "d", ctrl: function(){ console.log('my ctrl'); }, ctrl2: yourCtrl }, yourCtrl; return dir; yourCtrl = function(){ console.log('your ctrl'); }; }
js預編譯時,會掃描作用域, 將作用域內的函數聲明提升到作用域頂部。而執行代碼還在原位。
例如
function(){ console.log('start'); var a = 1; } 經過預編譯后,會變成: function(){ var a; console.log('start'); a = 1; }
即使這個var a在if的花括號內,也會被提前。
所以,我們常常強調的編碼規范還是很有存在意義的!