首頁  >  文章  >  web前端  >  JavaScript學習筆記(三):JavaScript也有入口Main函數_javascript技巧

JavaScript學習筆記(三):JavaScript也有入口Main函數_javascript技巧

WBOY
WBOY原創
2016-05-16 15:39:422010瀏覽

在C和Java中,都有一個程式的入口函數或方法,即main函數或main方法。而在JavaScript中,程式是從JS原始檔的頭部開始運作的。但某種意義上,我們還是可以虛構出一個main函數來作為程式的起點,這樣一來不僅可以跟其他語言統一了,而且說不定你會對JS有更深的理解。

1. 實際的入口

當把一個JavaScript檔案交給JS引擎執行時,JS引擎就是從上到下逐條執行每個語句的,直到執行完所有程式碼。

2. 作用域鏈、全域作用域與全域物件

我們知道,JS中的每個函數在執行時都會產生一個新的作用域。具體來說,在執行流程進入函數時會建立一個新的作用域,在函數執行完成退出時會銷毀這個作用域。函數的形參、局部變數都會綁定到這個作用域裡,當函數呼叫完成作用域銷毀時,它們隨之被銷毀。當然在特殊情況下,如果函數返回時作用域中的某些變數仍然被引用,那麼作用域以及這些被引用的變數就不會被銷毀,從而形成所謂的閉包。

另一方面,我們知道函數是可以巢狀的,因而作用域也是可以嵌套的。函數在定義的時候,JS引擎會為每個函數設定一個稱為[[scope]]內建屬性,它指向外部函數的詞法作用域。透過這種方式,多個作用域形成了鍊式結構,稱為作用域鏈。通常情況下,在任意時刻只存在一條作用域鏈,即從正在執行的函數的作用域開始,層層上溯,直到最外層的全局作用域。

[註]:作用域鏈上的函數就是JS源碼裡的層層巢狀的函數,跟函數執行時的順序或函數呼叫棧無關,這也是詞法作用域這個稱呼的由來。

全域作用域是一個特殊的作用域,它不是一個函數作用域,但它是所有函數作用域的外層作用域,也是所有作用域鏈的終點。因此只要程式沒有退出,全域作用域總是存在的,全域作用域內的變數也是一直有效的。

[函數3的作用域]-->[函數2的作用域]-->[函數3的作用域]-->[全域作用域]

另外,對應於全域作用域,還有一個全域物件。在瀏覽器中,全域物件就是window物件。全域物件是個特殊的物件:

在全域作用域中定義的變量,都會綁定到全域物件。

在任意作用域中定義的變量,如果定義時沒有用 var 關鍵字,都會綁定到全域物件。

在全域作用域中, this 指向全域物件。

從上面列舉的這些特性可以看出,如果把全域作用域當成一個物件的話,那麼實際上它就是全域物件。另外,這也解釋了在全域作用域中,以下的四個語句為什麼是等價的:

var a = 1;
a = 1;
window.a = 1;
this.a = 1;

3. 虛構的main函數

既然都是作用域,為什麼要有一個特殊的全域作用域呢?我們總是喜歡簡化、一致性,而盡量避免複雜、特殊。所以很自然地,我們會想能否讓全域作用域看起來跟函數作用域沒什麼兩樣?答案是肯定的。我們可以做這樣的構想:

 我們想像,在JS引擎執行原始檔時,會將檔案中的程式碼包裝到一個叫做main的函數中。然後把這個main函數當作程式的入口。
也就是說,假設一個JS檔中有這樣的程式碼:

var a = 1;
var b = 2;

function add(x, y) {
  var z = x + y;
  return z;
}
console.log(add(a, b));

JS引擎在程式開始執行前會把它包裝成一個main函數:

// 虚构的main函数
function main() {
  var a = 1;
  var b = 2;

  function add(x, y) {
    var z = x + y;
    return z;
  }

  console.log(add(a, b));
}

然後,呼叫這個main函數:

main._current_scope_ = window; // 将全局作用域(对象)设为window
main.call(window) // 将this指向window

4. 意義何在?

(1) JS也有了入口函數main,跟其他語言一致了。

(2) 省去了全域作用域的概念,或者說全域作用域也成了函數作用域。

(3) 透過上面對main函數的呼叫過程,可以明白全域作用域中的那些特殊性質的由來。

(4) 最後一點,將所有JS源碼當成一個函數,是為了後面講事件佇列、事件循環做鋪墊。

以上就是小編給大家介紹的JavaScript學習筆記(三):JavaScript也有入口Main函數,希望大家喜歡。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn