iidear / blog

blog
0 stars 0 forks source link

ECMAScript 2015 #6

Open iidear opened 5 years ago

iidear commented 5 years ago

http://www.ecma-international.org/ecma-262/6.0/index.html

iidear commented 5 years ago

ECMAScript 历史

ECMAScript 最早出现在网景的 Navigator 2.0 浏览器中,由 Brendan Eich 发明。

1997年6月,ECMAScript 1.0

1998年4月,ECMAScript 2.0

1999年12月,ECMAScript 3.0

几乎所有浏览器都支持,引入了以下功能

ECMAScript 4.0 未发布

2009年12月,ECMAScript 5.0

将浏览器的普遍实现定义为规范,增加的以下新特性

2011年6月,ECMAScript 5.1

修订错误

2015年6月,ECMAScript 2015

iidear commented 5 years ago

语言说明

Scope: This Standard defines the ECMAScript 2015 general purpose programming language.

general purpose programming language

通用目的编程语言(eg. C、Java、Python、JavaScript

In computer software, a general-purpose programming language is a programming language designed to be used for writing software in the widest variety of application domains (a general-purpose language). wikipedia

领域特定编程语言(eg. HTML、SQL、MATLAB、Verilog

A domain-specific language (DSL) is a computer language specialized to a particular application domain.wikipedia

object-oriented programming language

Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which may contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. A feature of objects is that an object's procedures can access and often modify the data fields of the object with which they are associated (objects have a notion of "this" or "self").wikipedia

Class-based vs prototype-based

In class-based languages the classes are defined beforehand and the objects are instantiated based on the classes. In prototype-based languages the objects are the primary entities. No classes even exist. The prototype of an object is just another object to which the object is linked. Every object has one prototype link (and only one). New objects can be created based on already existing objects chosen as their prototype.

最初被设计为scripting language

A scripting language is a programming language that is used to manipulate, customize, and automate the facilities of an existing system.

原型链

function Person() {}
var p = new Person()
p.__proto__ === Person.prototype // true

Person.prototype.name = 'xx'
p.name // 'xx'
iidear commented 5 years ago

ECMAScript 的解释与执行

规范章节安排大致如下:

规范先讲了 ECMAScript 语言的数据类型(ECMAScript Language Types)

为了解释语言的语义而定义的抽象数据结构(ECMAScript Specification Types)

为了解释语言的语义而定义的抽象操作

代码解释执行过程中涉及的数据结构与方法

为实现对象的特性而定义的对象内部方法与状态

语言的词法、语法和语义

标准库。

整个规范需要来来回回读。借助xmind做笔记

iidear commented 5 years ago

ECMAScript 的解释与执行(二)

从源代码到 AST

《编译原理》 前2~3章,可以理解上下文无关语法与基础的词法分析、语法分析方法。

const PREFIX = 'hello, ';
function sayHi(name) {
  console.log(PREFIX + name)
}
var name = 'world';
sayHi(name);

对于上面代码,解析为AST。AST explorer

AST
iidear commented 5 years ago

ECMAScript 的解释与执行(三)

Lexical Environments

词法环境:根据代码的词法结构生成。由一个环境记录和一个外层词法环境的引用组成。

A Lexical Environment is a specification type used to define the association of Identifiers to specific variables and functions based upon the lexical nesting structure of ECMAScript code.A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment.

环境记录:记录了相关词法环境作用域的标识符绑定。

An Environment Record records the identifier bindings that are created within the scope of its associated Lexical Environment.

ECMAScript 定义了五种生成不同词法环境的抽象方法

Code Realm

ECMAScript 是基于对象的语言。Code Realm 存放了语言的固有对象和全局环境。

Before it is evaluated, all ECMAScript code must be associated with a Realm.

Execution Contexts

执行上下文用于跟踪代码执行的运行时。执行上下文栈用于记录上下文的切换,栈顶为当先执行上下文。 一个执行上下文通常由以下几部分组成:

对于 ECMAScript 代码,执行上下文还包括:

Jobs and Job Queues

ECMAScript 至少实现两种任务队列: ScriptJobs PromiseJobs

ECMAScript 初始化流程

  1. 创建 Code Realm
    1. 创建固有对象,设置为 realm.[[intrinsics]]
    2. realm.[[globalThis]] = undefined
    3. realm.[[globalEnv]] = undefined
    4. realm.[[templateMap]] = empty List
  2. 创建执行上下文 newContext
    1. newContext.[Function] = null
    2. newContext.[Realm] = realm
    3. 入栈 newContext
  3. 初始化全局对象
    1. realm.[[globalThis]] = globalObj(globalObj 可由宿主环境指定,eg. Window)
    2. realm.[[globalEnv]] = NewGlobalEnvironment(globalObj)
    3. 将realm.[[intrinsics]] 中的大部分固有对象设置为 globalObj 的属性
    4. 宿主环境设置自定义的 globalObj 的属性
  4. 入队源码执行任务
    1. 创建任务 PendingJob{[[Job]]: job, [[Arguments]]: « sourceText », [[Realm]]: callerRealm, [[HostDefined]]:undefined}. (job 为 ScriptEvaluationJobTopLevelModuleEvaluationJob)
    2. 宿主环境对 PendingJob 进行处理
    3. 入队 PendingJob 到任务队列 ScriptJobs
  5. 启动任务队列下一个任务
    1. 暂停并出栈当前执行上下文
    2. 找到一个非空任务队列,出队一个任务 nextPending
    3. 创建一个执行上下文 newContext
    4. newContext.[Realm] = nextPending.[[Realm]]
    5. 入栈 newContext
    6. 宿主环境初始化 nextPending 任务
    7. 执行 nextPending.[[Job]] 指定的抽象操作 ScriptEvaluationJob
  6. ScriptEvaluationJob 对源码进行解释执行
    1. 将源码根据语法规则解析为 AST
    2. 解释执行 AST
iidear commented 5 years ago

https://ecma-international.org/ecma-262/9.0/index.html#sec-context-free-grammars