簡體   English   中英

在 javascript V8 中,編譯階段在執行階段之前發生在函數上,然后執行所有代碼或僅針對全局上下文

[英]In javascript V8 does compilation phase happen to functions before execution phase then all the code is executed or only for global context

我讀了很多文章,說編譯(創建)階段首先發生在全局執行上下文中,然后代碼被執行,當一個函數被調用時,創建階段然后再次為這個函數開始,然后它被執行這是真的發生了什么嗎? 為什么所有代碼​​都沒有發生創建階段,首先包括函數內部的變量,然后所有代碼都被執行,因為這樣創建階段是執行階段本身的一部分,引擎在執行之前不知道函數內部的哪些變量階段如果是這樣為什么這樣的事情會在沒有先登錄到控制台的情況下出錯

 console.log('First No Error') function Error() { let a = 2 console.log(z) } Error()

它給出了引用錯誤,因為 z 沒有首先在沒有登錄到控制台(無錯誤)的情況下定義,為什么會發生這種情況,因為引擎不應該知道函數內部存在錯誤,直到它只在最后一行執行。

我想知道函數內部已知的內容,並且可以在函數本身執行之前使用它(即使它只是一個沒有內存中真實數據的引用,並且當它成為內存中的真實數據時)。

(此處為 V8 開發人員。)

編譯(創建)階段

這是兩個不同的東西。 “創建階段”是一些人提出的一個概念,目的是向其他人(比如你)解釋 JavaScript 引擎的作用。 如果您發現它更令人困惑而不是有幫助,您可能應該將反饋直接發送給他們:-)

“編譯”是一個引擎內部的實現細節:一些引擎可能會將 JavaScript 源代碼編譯為字節碼或機器碼或兩者兼而有之,而其他引擎可能不會; JavaScript 語言規范對此沒有意見。 你在現代瀏覽器中發現的 JavaScript 引擎都做各種形式的編譯和重新編譯; 細節取決於每個引擎,並且不時發生變化。 在基於編譯思想構建的引擎中,編譯必須在執行之前發生(因為它是將被執行的編譯結果),但多長時間並不重要:它可能發生在第一次執行之前,或者很久以前它。

JavaScript 規范確實要求引擎在看到代碼時立即報告某些錯誤(“早期錯誤”)。 因此引擎必須立即查看所有代碼,至少要找到這些類型的錯誤。 但這與編譯任何東西都不一樣。 (並且console.log(z)不是早期錯誤的一個例子。)

JavaScript 引擎喜歡將任何不需要的工作推遲到以后,以保持快速啟動。 讓網站加載得更快是一種更好的用戶體驗,而且由於頁面加載通常只涉及頁面的一些資源(例如:只有一些 JS 函數被調用,只有一些圖像被顯示),瀏覽器可以加快速度的一種方式頁面加載只執行加載所需的操作:像編譯那些只會在以后調用的函數,以及下載那些只會在以后顯示的圖像之類的工作,可以推遲到實際需要時。

它給出了參考錯誤,因為沒有首先登錄到控制台(無錯誤)就沒有定義 z 為什么會發生這種情況

這不是正在發生的事情; 在引發 ReferenceError 之前記錄“First No Error”。 試試看!

我想知道函數內部已知的內容,並且可以在執行函數本身之前使用它。

在相應的代碼運行時創建對象並初始化變量。 定義函數時,可以引用函數外部(詞法)作用域中的任何變量。 例如:

function f1() {
  console.log(a);  // This will be fine.
  console.log(b);  // This will be an error (at execution time).
  console.log(c);  // This will be an error (at execution time).
  console.log(d);  // This will log 'undefined'.
}

// This is in f1's outer scope, so f1 can use it.
// For better readability, I would recommend to define variables like `a`
// before defining the functions that use them (like f1), but that's not
// a JavaScript requirement, just a recommendation for human readers.
var a = 42;

function f2() {
  var b = 123;  // This is not in f1's outer (lexical) scope.
  f1();
}
f2();

// This is in f1's outer scope, but only created after f1 is called.
// Contrary to `var` variables, `let` variables are not hoisted to the
// beginning of their scope, so are (sort of) "invisible" before.
let c = 77;
// f1 will be able to see the existence of this variable, but its value
// will only be set after the call (when execution reaches this point here),
// so within f1 it will be `undefined`.
var d = 88;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM