Giter VIP home page Giter VIP logo

front-end-plan's People

Contributors

nightn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

front-end-plan's Issues

關於 JS 作用域裡面的解釋

您好,首先先感謝你的詳細解釋,我覺得 JS 作用域這篇的思路特別好,透過 JS 引擎在執行時候的觀點可以把一些知識點講解的很清楚,例如說作用域跟變量提升。

然而我這邊有一個小問題,文章裡面說到:每当 JS 引擎发现一个函数调用 (注意是调用,而不是声明),它就会创建一个新的函数执行环境。,我想問一下如果是這樣的話,該如何解釋閉包?

例如說以下代碼:

function giveMeClosure() {
  var count = 0
  function closure() {
    console.log(count++)
  }
  return closure
}

var func = giveMeClosure()
func()

在最後一行的 func() 之前都沒有調用裡面的 closure,可是這時候因為已經離開了 giveMeClosure,它的執行環境已經被銷毀,這樣就沒辦法解釋閉包如何存取到 giveMeClosure 執行環境的活動變量。

想請問這一個部分應該如何解釋,是不是其實在聲明函數的時候就已經有創建作用域鏈了?或是有其他機制可以解釋這個行為?

感謝

有關於「編譯階段」

Hi,先再次感謝你上次的耐心回復以及資源推薦,我後來把你推薦的系列文章稍微看過一遍,真的是收穫滿滿,不過與此同時,卻也產生了一些疑問想與你交流一下。

你在 JS 作用域裡面寫到了:

JS引擎在分析 JS 代码时分为两个过程,一个是编译阶段,另一个是执行阶段。编译阶段主要是处理代码中的变量和函数声明,执行阶段才开始执行具体语句。当 JS 代码加载完成后,JS 引擎首先进行代码的编译阶段,它会在这个编译阶段创建执行环境,JS 引擎通过 3 个步骤完成执行环境的创建:

创建活动对象或者变量对象:活动对象是 JS 中的一个特殊对象,它包含了当前执行环境所有的变量、函数参数和内部函数声明。活动对象和普通对象不同,它没有 proto 原型属性。

创建作用域链:活动对象创建完毕后,JS 引擎会初始化作用域链,作用域链其实就是一个存放了很多变量对象的列表,包括了从全局执行环境的变量对象到当前函数执行环境的变量对象的所有变量对象。JS 引擎就是通过这个作用域链进行变量查找的。

确定 this 的值:初始化作用域链后,JS 引擎开始确定 this 的值。关于 this 的确定,我会用专门的一节进行阐述。

這樣的說法其實在一些國外的英文文章上面也很常見,就是把 JS 分成編譯階段跟執行階段,但我這邊有一個問題,那就是 JS 不是解釋型的語言嗎?

我之前在看跟 JS 相關的資料時也對這塊有點疑惑,後來看到了虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩這篇文章,解除了大部分疑惑。

JS 雖然是解釋型語言,但不代表裡面不能有編譯的步驟,舉例來說,你今天用 V8 跑一段程式碼,你輸入 JS 之後,V8 一樣會輸出程式碼的「執行結果」,而不是輸出編譯過後的程式碼,這符合解釋型的定義,但在 V8 裡面的確是有對 JS 進行編譯的。

可是在一個語言的規範裡面,一般來說好像並不會提到這個語言是解釋執行還是編譯執行,例如説 ECMAScript 就沒有提到這件事。因此就我的理解,當提到 JavaScript 的「編譯階段」時,已經依賴於某個特定實作了(例如說 V8)。

所以文章中的那一段「JS 引擎分析 JS 代碼分成兩個過程」,或許代換為「V8 引擎(特定實作)分析 JS 代碼分成兩個過程」會比較洽當一點?因為不是所有 JS 引擎都有編譯階段。

或者我認為比較好的說法是,參考 ECMA-262-3 in detail. Chapter 2. Variable object. 裡面提到的:

Phases of processing the context code

Now we have reached the main point of this article. Processing of the execution context code is divided on two basic stages:

  1. Entering the execution context;
  2. Code execution.

其實「创建活动对象或者变量对象」、「创建作用域链」以及「确定 this 的值」這三件事,都是在「進入執行環境」時這個階段發生的,所以跟編譯不編譯一點關係都沒有,跟執行比較有關係。

所以在談 ECMAScript 的時候,我們可以完全不談「編譯」這個字眼,因為規格上也沒有要求你一定要編譯,而只是寫說你在進入一個執行環境時,必須要把這些東西創建好,接著下一步才是真的執行這個執行環境裡面的代碼。

以上是我的一些想法,不知道你怎麼看?

感謝。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.