ECMAScript 7th edition S4

4. 概述

本节包含对 ECMAScript 语言非规范性的概述。

ECMAScript 是在宿主环境中执行计算,处理对象的面向对象编程语言。这里定义的 ECMAScript 并未打算要计算性自足。事实上,本规范没有任何针对输入外部数据或输出计算结果的条文。相反,我们期望 ECMAScript 程序的计算环境可提供本规范中描述的对象和其它设施之外的、某些特定环境下的 宿主 (host) 对象,除了说明宿主对象应该提供可被 ECMAScript 程序访问的某些属性,调用的某些方法外,关于它的其他描述和行为超出了本规范涉及的范围。

ECMAScript 是脚本语言。脚本语言又被称为扩建的语言,或者动态语言,是一种编程语言,用来控制软件应用程序,脚本通常以文本(如ASCII) 保存,只在被调用时进行解释或编译。现有系统给了脚本语言需要的宿主环境,脚本语言来完善现有的系统。脚本语言更加简单,专业或非专业的程序员都可以使用。

ECMAScript 最初被设计为 Web 脚本语言,它提供了一种机制,使浏览器里的网页更加活跃。ECMAScript 可以为各种宿主环境提供核心的脚本功能,因此本文档为不依赖特定宿主环境的核心脚本语言作出规范。

ECMAScript 的一些机能和其他编程语言的类似;特别是 Java™,Self,和 Scheme。以下文献描述了他们:

ISO/IEC 9899:1996, Programming Languages – C.

Gosling, James, Bill Joy and Guy Steele. The Java™ Language Specification. Addison Wesley Publishing Co., 1996.

Ungar, David, and Smith, Randall B. Self: The Power of Simplicity. OOPSLA '87 Conference Proceedings, pp. 227-241, Orlando, FL, October 1987.

IEEE Standard for the Scheme Programming Language. IEEE Std 1178-1990.

4.1 Web 脚本语言

WEB 浏览器为引入客户端计算能力而提供 ECMAScript 宿主环境,例如,它提供的对象有:windows,menus,pop-ups,dialog boxes,text areas,anchors,frames,history,cookies 及 输入/输出 等等。进一步来说,Web浏览器 提供了一种方式,使得脚本代码可以去处理诸如改变焦点、页面和图片的加载卸载、错误和放弃、选择、表单提交和鼠标交互等等事件。脚本代码出现在 HTML 中,显示出来的页面是一个用户接口元素与固定的和计算出来的文本和图片的集合。脚本代码根据用户的交互而做出反应,并不需要存在一个主程序。

WEB 服务器为了服务端的计算则提供了一个完全不一样的宿主环境,包括的对象有:requests,clients,files 以及数据锁定和分享的机制。通过浏览器端脚本及服务端脚本的配合使用,在为基于 WEB 方式的应用程序提供定制的用户接口时,可以将计算分布到客户端和服务端进行。

每一种支持 ECMAScript 的 WEB 浏览器和服务器都将它们自身作为宿主环境,将 ECMAScript 作为补充,以使得 ECMAScript 的执行环境变得完整。

4.2 语言概述

下面是非正式的 ECMAScript 概述,并未描述语言的所有部分。此概述并非标准的一部分。

ECMAScript 是基于对象的:基本语言和宿主设施都由对象提供,ECMAScript 程序是一组可通信的对象。ECMAScript 对象 (objects) 是 属性 (properties) 的集合,每个属性有零个或多个 特性 (attributes),它确定怎样使用此属性。例如,当设置一个属性的 Writable 特性为 false 时,任何试图更改此属性值的 ECMAScript 代码的都会运行失败。属性是持有其他 对象 (objects), 原始值 (primitive values), 函数 (functions) 的容器。原始值是以下内置类型之一的成员:Undefined,Null,Boolean,Number,String;对象是剩下的内置类型 Object 的成员;函数是可调用对象 (callable object)。方法 (method) 是通过属性与对象关联的函数。

ECMAScript 定义一组内置对象,勾勒出 ECMAScript 实体的定义。这些内置对象包括一些全局对象 (global object)。其中有基础对象包括 Object、Function、Boolean、Symbol以及各种 Error (EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError);数值相关的对象包括 Math、Number、Date;文本处理对象包括 String、RegExp;对象还是包括数列及其它九种有特定值的数据结构的基础索引;键的合集包括 Map 和 Set 都是对象;对象支持的数据结构包括 JSON 对象、ArrarBuffer 和 Dataview;对象支持的抽象方法包括 generator 和 Promise 对象;最后还有反射对象比如说 Proxy 和 Reflect。

ECMAScript 中还定义一组内置运算符 (operators)。ECMAScript 运算符包括 一元运算符,乘法运算符,加法运算符,按位移位运算符,关系运算符,相等运算符,二进制位运算符,二进制逻辑运算符,赋值运算符,逗号运算符。

大型的 ECMAScript 也支持模块化,它允许程序被分为若干小的语句和声明。每一个模块都要有一个明确的声明来显示它调用了其它的哪个模块以及它可以被那一个模块调用。

ECMAScript 语法有意设计成与 Java 语法类似。ECMAScript 的语法是松散的,使其能够作为一个易于使用的脚本语言。例如,一个变量不需要有类型声明,属性也不需要与类型关联,定义的函数也不需要声明在函数调用词句的前面。

4.2.1 对象

ECMAScript 不使用诸如 C++,Smalltalk,Java 中的类(class)。相反,对象可以通过各种方式创建,包括字面符号,或通过 构造器 创建对象然后运行代码初始化其全部或部分属性值,为这些属性分配初始值。每个构造器是一个拥有名为 prototype 的属性的函数。此属性用于实现 基于原型的继承 和 共享属性 。构造器通过 new 表达式创建对象:例如,new Date(2016, 10) 创建一个新 Date 对象。不使用 new 调用一个构造器的结果,依赖构造器本身。例如,Date() 产生一个表示当前日期时间的字符串,而不是一个对象。

每个由构造器创建的对象,都有一个隐式引用 (叫做对象的原型) 链接到构造器的 prototype 属性值。再者,原型可能有一个 非空(non-null) 隐式引用链接到它自己的原型,以此类推,这叫做 原型链 。当向对象的一个属性提出引用,引用会指向原型链中包含此属性名的第一个对象的此属性。换句话说,首先检查直接提及的对象的同名属性,如果对象包含同名的属性,引用即指向此属性,如果该对象不包含同名的属性,则下一步检查对象的原型;以此类推。

一般情况下基于类的面向对象语言的实例拥有状态,类拥有方法,并且只能继承结构和行为。在 ECMAScript 中,对象拥有状态和方法,并且结构,行为,状态全都可继承。

不直接包含原型中包含的特定属性的所有对象会共享此属性及属性值。图1 说明了这一点:

MacDown logo

CF 是一个构造器 (也是一个对象)。五个对象已用 new 表达式创建:cf1, cf2, cf3, cf4, cf5。每个对象都有名为 q1 和 q2 的属性。虚线表示隐式原型关系;例如:cf3 的原型是 CFp。构造器 CF 自己有名为 P1 和 P2 的两个属性, 这对 CFp, cf1, cf2, cf3, cf4, cf5 是不可见的。CFp 的名为 CFP1 的属性共享给 cf1, cf2, cf3, cf4, cf5 (没有 CF), 以及在 CFp 的隐式原型链中找不到任何名为 q1, q2, 或 CFP1 的属性。请注意,CF 和 CFp 之间没有隐式原型链接。

不同于基于类的对象语言,属性可以通过赋值的方式动态添加给对象。也就是说,构造器并不是非要对构造的对象的全部或任何属性命名或赋值。上图中,可以用给 CFp 添加新属性值的方式为 cf1, cf2, cf3, cf4, cf5 添加一个新的共享属性。

虽然 ECMAScript 之前并未定义 类(class) 这一概念,但是在构造函数,原型对象,属性方法这些部分如果有 类(class) 这一概念的话会方便很多。因此从 ECMAScript 2015 开始便新增了 类(class) 的语法,允许程序员使用它简洁地写出 类(class) 这样的结构。

4.2.2 ECMAScript 的严格模式变体

ECMAScript 语言认可有些用户希望限制使用语言中某些功能的可能性。他们这样做可能是为了安全考虑,避免他们认为是容易出错的功能,获得增强的错误检查,或其他原因。为了支持这种可能性,ECMAScript 中定义了语言的严格变体。语言的严格变体,排除了 ECMAScript 语言的某些特定的语法和语义特征,还修改了某些功能的详细语义。严格变体还指定了必须抛出错误异常报告的额外错误条件,即使在非严格的语言形式下这些条件不属于错误。

ECMAScript 的严格变体通常被称为语言的 严格模式 (strict mode)。严格模式选择使用的 ECMAScript 严格模式的语法和语义,明确地适用于个别 ECMAScript 代码单元级别。由于严格模式适用于选择的语法代码单元级别,严格模式仅在这个代码单元内施加有局部效果的限制。严格模式不限制或修改任何必须运行在多个代码单元的 ECMAScript 语义层面。一个 ECMAScript 程序可由严格模式和非严格模式的代码单元组成。在这种情况下,严格的模式只适用于严格模式代码单元内实际执行的代码。

要符合这一规范,ECMAScript的实现必须同时实现未限制的ECMAScript语言和按照这个规范定义的ECMAScript的严格模式变体。此外,实现还必须支持未限制的和严格模式代码单元的在同一个程序中混用。

4.3 术语定义

本文档将使用下列术语和定义。

4.3.1 数据类型 (type)

本规范第 6 章定义数据的集合。

4.3.2 原始值 (primitive value)

本规范第六章定义的 Undefined, Null, Boolean, Number, Symbol, String 这些值之一。

注意:原始值代表语言实现的最底层的数据。

4.3.3 对象 (object)

对象类型的成员。

注意:对象是属性的集合,并有一个原型对象。原型可以是为 null。

4.3.4 构造器 (constructor)

创建和初始化对象的函数对象。

注意:构造器的 prototype 属性值是一个原型对象,它用来实现继承和共享属性。

4.3.5 原型 (prototype)

为其他对象提供共享属性的对象。

注意:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的 prototype 属性。通过程序表达式 constructor.prototype 可以引用到构造器的 prototype 属性,并且添加到对象原型里的属性,会通过继承与所有共享此原型的对象共享。另外,可使用 Object.create 内置函数,通过明确指定原型来创建一个新对象。

4.3.6 普通对象 (ordinary object)

有 默认行为 和 所有对象都支持的基本方法 的对象。

4.3.7 外来对象 (exotic object)

不含或少含 所有对象都支持的基本方法 的对象。

注意:任何对象只要不是普通对象就是外来对象。

4.3.8 标准对象 (standard object)

任何语义符合本标准的对象。

4.3.9 内置对象 (built-in object)

由 ECMAScript 标准规定并提供的对象。

注意:本标准制定了标准的内置对象。一个 ECMAScript 可能会包含其它更多内置对象。内置构造器是构造器,同样也是内置对象。

4.3.10 未定义值 (undefined value)

原始值,一个变量未被赋值时的默认值。

4.3.11 未定义类型 (Undefined type)

仅有 undefined 一个值的数据的类型。

4.3.12 空值 (null value)

原始值,任何有意使其为空的对象的值。

4.3.13 空类型 (Null type)

仅有 null 一个值的数据的类型。

4.3.14 布尔值 (Boolean value)

布尔类型中的一个。

注意:布尔类型只有 true 和 false 两个值。

4.3.15 布尔类型 (Boolean type)

由 true 和 false 两个值构成的类型。

4.3.16 布尔对象 (Boolean object)

本标准内置的布尔构造器生成的实例。

注意:布尔对象是内置的布尔构造器用 new 关键字生成的示例,提供布尔值作为参数,得到的对象会内部会有一个布尔值。布尔对象可以被强制转换为布尔值。

4.3.17 字符串值 (String value)

原始值,一个有限序列或是零个或多个 16 位无符号整数。

注意:字符串值是字符串类型的成员。序列中的每个整型值通常代表一个 16位 utf-16 单元的文本。然而,除了必须是 16位 无符号整数以外,ECMAScript 没有其它任何限制或要求。

4.3.18 字符串类型 (String type)

所有可能的字符串的集合。

4.3.19 字符串对象 (String object)

本标准内置的字符串构造器生成的实例。

注意:字符串对象是内置的字符串构造器用 new 关键字生成的示例,提供字符串作为参数,得到的对象内部会有一个字符串。通过调用字符串构造器 (21.1.1.1),字符串对象可以被强制转换为字符串值。

4.3.20 数值 (Number value)

原始值,是一个 64 位双精度二进制值,符合 IEEE754 规定。

注意:数值是数值类型的成员,直接表现为一个数字。

4.3.21 数值类型 (Number type)

所有数值的集合,包括 “Not-a-Number” (NaN) 值,正无穷和负无穷。

4.3.22 数值对象 (Number object)

本标准内置的数值构造器生成的实例。

注意:数值对象是内置的数值构造器用 new 关键字生成的示例,提供数值作为参数,得到的对象内部会有一个数值。通过调用数值构造器 (21.1.1.1),数值对象可以被强制转换为数值。

4.3.23 无穷大 (Infinity)

数值,指正无穷。

4.3.24 非数值类型 (NaN)

数值,是 IEEE 754-2008 规定的 “Not-a-Number” 值。

4.3.25 符号值 (Symbol value)

原始值,代表一个独一无二的,非字符串对象的属性值。

4.3.26 符号类型 (Symbol type)

所有可能的符号值的集合。

4.3.27 符号对象 (Symbol object)

内置符号构造器生成的示例。

4.3.28 函数 (function)

对象类型中可被当作子程序调用的一类。

注意:函数除了拥有属性,还包含可执行代码、状态,用以确定被调用时的行为。函数的代码不限于只用 ECMAScript 书写。

4.3.29 内置函数 (built-in function)

是函数的内置对象。

注意:内置函数包含例如 parseInt 和 Math.exp 这样的函数。标准的实现可能包含本标准中未包含的额外的内置函数。

4.3.30 属性 (property)

对象的一部分,是键值对的键 (字符串类型或者符号类型)。

注意:属性可能根据属性值的不同表现为直接的数据值(原始值,对象,或一个函数对象)或间接的一对访问器函数。

4.3.31 方法 (method)

是函数的属性值。

注意:当一个函数被叫做某对象的方法,该对象将作为 this 关键字传给该函数。

4.3.32 内置方法 (built-in method)

是内置函数的方法。

注意:标准内置方法由本规范定义,一个 ECMAScript 实现可指定,提供其他额外的内置方法。

4.3.33 特性 (attribute)

属性内部定义的一些的特定值。

4.3.34 自身属性 (own property)

对象直接拥有的属性。

4.3.35 继承属性 (inherited property)

不是对象的自身属性,是对象原型的属性 (原型的自身属性或继承属性)。

4.4 本规范的结构

本规范剩余篇幅将会以以下结构展示:

第 4 部分将会介绍贯穿本规定始终的记法约定。

第 6 部分至第 9 部分介绍 ECMAScript 在何种环境下执行。

第 10 部分至第 16 部分介绍 ECMAScript 语言的所有语义及语法特性。

第 17 部分至 26 部分记录了 ECMAScript 标准库。它包括当 ECMAScript 标准执行时所有的标准对象。