若是咱們使用 匿名函數express
var FUNCTION_NAME = function() { /* FUNCTION_BODY */};
這種方式, 編譯後變量聲明FUNCTION_NAME 會「被提早」了,可是他的賦值(也就是FUNCTION_BODY)並不會被提早。
也就是說,匿名函數只有在被調用時才被初始化。
若是咱們使用函數
function FUNCTION_NAME () { /* FUNCTION_BODY */};
這種方式, 編譯後函數聲明和他的賦值都會被提早。
也就是說函數聲明過程在整個程序執行以前的預處理就完成了,因此只要處於同一個做用域,就能夠訪問到,即便在定義以前調用它也能夠。
code
function hereOrThere() { //function statement return 'here'; } alert(hereOrThere()); // alerts 'there' function hereOrThere() { return 'there'; }
咱們會發現alert(hereOrThere) 語句執行時會alert('there')!這裏的行爲其實很是出乎意料,主要緣由是JavaScript 函數聲明的「提早」行爲,簡而言之,就是Javascript容許咱們在變量和函數被聲明以前使用它們,而第二個定義覆蓋了第一種定義。換句話說,上述代碼編譯以後至關於ip
function hereOrThere() { //function statement return 'here'; } function hereOrThere() {//申明前置了,但由於這裏的申明和賦值在一塊兒,因此一塊兒前置 return 'there'; } alert(hereOrThere()); // alerts 'there'
再看下面一個例子:作用域
var hereOrThere = function() { // function expression return 'here'; }; alert(hereOrThere()); // alerts 'here' hereOrThere = function() { return 'there'; };
這裏就是咱們期待的behavior,這段程序編譯以後至關於:
io
var hereOrThere;//申明前置了 hereOrThere = function() { // function expression return 'here'; }; alert(hereOrThere()); // alerts 'here' hereOrThere = function() { return 'there'; };