ECMA-262 V7.0 中关于数据类型和值的说明

来源:互联网 发布:软件类企业安全教育 编辑:程序博客网 时间:2024/06/05 23:51

原文 http://www.ecma-international.org/ecma-262/7.0/index.html#sec-ecmascript-data-types-and-values

6 ECMAScript数据类型和值

这篇规范中的算法操作的每一个值都有一个对应的类型。在这节中给出所有可能的类型的明确定义。类型进一步被分为ECMAScript语言类型和规范类型。术语empty用来表示没有任何值。

6.1 ECMAScript语言类型

ECMAScript语言类型直接被ECMAScript程序员所使用。ECMAScript语言类型是:Undefined, Null, Boolean, String, Symbol, Number 和 Object。一个ECMAScript语言值是具有一个ECMAScript语言类型特征的值。

在这片手册中Type(x)表示x的类型,类型是再ECMAScript语言类型和规范类型中定义的。

6.1.1 undefined类型

undefined类型只有一个叫做undefined的值。任何没有被赋过值的变量具有值undefined。

6.1.2 null类型

null类型只有一个叫做null的值。

6.1.3 boolean类型

boolean类型表示一个逻辑实体,具有两个值,true和false。

6.1.4 string类型

string类型是0或更多无符号16位整数值的有序集合,最多2^53-1个元素。string类型经常用来表示文本数据,这种情况下每一个元素是一个UTF-16编码的单一值。每一个元素占据序列中一个位置。位置的索引是一个非负值。第一个元素(如果存在的话)在索引0,下一个(如果存在的话)在索引1,如此下去。string的长度是它其中元素(例如,16位的值)的个数。空的string的长度是0因此不包含元素。

在ECMAScript操作中解释string的值时,每一个元素被解释为一个单一的UTF-16编码的单元。然而ECMAScript不对String编码单元的序列做任何限制和要求,所以当转换为UTF-16编码单元时它们可能是不规范的。不需要解释字符串内容的操作将字符串内容视为无差别的16位无符号整数的序列。函数String.prototype.normalize(参照21.1.3.12)可以用来显式地标准化一个字符串值。String.prototype.localeCompare(参照21.1.3.10)会在内部标准化字符串值,没有其他操作会暗中对字符串进行标准化。只有明确对语言和区域有特定要求的操作才会导致语言敏感的结果。
注解: 字符串设计的基本原则是尽可能保持简单和高性能。如果ECMAScript的源文本是标准C格式(参照http://www.unicode.org/reports/tr15/#Normalization_Forms_Table),字符串的文字也可以被规范化,只要它们不包含任何Unicode转义序列。

一些操作将字符串翻译为UTF-16编码的Unicode编码点。此时按照下面的步骤操作:

在值00xD7FF0xE0000xFFFF的编码单元表示为具有相同值的编码点。一个包含两个编码单元的序列,第一个编码单元c1在范围0xD8000xDBFF之间并且第二个编码单元在范围0xDC000xDFFF之间,是一个代理对(surrogate pair),并且它表示为具有值(c1 - 0xD800) × 0x400 + (c2 - 0xDC00) + 0x10000的编码点(参照10.1.2)。值在0xD8000xDFFF之间且不是替代对之一的编码单元,表示具有相同值的编码点。

6.1.5 symbol类型

Symbol类型是所有非字符串值的集合,可能被用来作为一个对象属性的键。
每一个可能的Symbol值是唯一且不可改变的。
每一个Symbol值永久保持一个不变的叫做[[Description]]关联值,它是undefined或字符串。

6.1.5.1 广为人知的symbol

广为人知的Symbol是内建Symbol值,它们被这篇文档中的算法明确引用。它们典型的应用是作为属性的键,属性的值用作特定算法的扩展点。除了特别指出,广为人知的Symbol值在所有领域(见8.2)共享。

在这篇文档中一个广为人知的Symbol被通过使用格式为@@name的声明引用,’name’是下表中的值之一。

表格1

6.1.6 数值类型

数值类型具有18437736874454810627(2^64-2^53+3)个值,表示为双精度64位IEEE 754-2008中的值,采用IEEE标准所指定的二进制浮点数算法,除了在IEEE标准中独特的表示非数字(Not-a-Number)的9007199254740990(2^53-2),它在 ECMAScript 中被表示为一个单一的特殊值NaN。(注意NaN值在程序中被表示为NaN。)在一些实现中,其他代码可能会认为多个非数字值是不同的,但是这种表现是依赖于实现的。在ECMAScript中,所有的NaN值是相同的。

注解:位模式可能被放入一个ArrayBuffer(数组缓存)进行观察,在一个数字值被放入其中后就不必采用和ECMAScript实现相同的内部数字表征。

此外还有两个特殊值被称作正无穷(positive Infinity)和负无穷(negative Infinity)。为了简介,这些值也被分别表示为 +∞ 和 -∞。(注意这两个值在程序内被表示为+Infinity (或Infinity) 和 -Infinity。)

其他的18437736874454810624 (2^64-2^53) 个值被成为有限数(finite numbers)。一半是正数,一半是负数。每一个有限正数都对应一个有限负数。

注意存在正0(positive zero) 和 负0(negative zero)。为了简介,他们分别被记作+0和-0。(注意这两个值在程序中被表示为+0 (或0) 和 -0。)

18437736874454810622 (2^64-2^53-2)个有限非零值分两种:

他们中的18428729675200069632 (2^64-2^54) 个是规范化的,具有格式:

s × m × 2^e

其中s是+1或-1,m是小于2^53且大于等于2^52的正整数,e是从 -1074(包括) 到 971(包括)的整数。

剩下的9007199254740990 (2^53-2)个值是非规范化的,具有格式:

s × m × 2^e

其中s是+1或-1,m是小于2^52的正整数,e为-1074。

注解:数字类型所能表示的所有正整数和负整数,他们的数字部分不能大于2^53(事实上,整数0具有+0和-0两种表示)。

在上面两种形式中如果m是奇数,那么这个有限整数是奇数,反之是偶数。

在这篇手册中,短语“x的数值(the Number value for x)”(x表示一个真实的准确的数学上的量(甚至可能是一个无理数,例如π))意味着一个数字符合下面的规范。考虑数字类型的所有有限值,不包括-0,包括两个附加的值2^1024 (+1 × 2^53 × 2^971) 和 2^1024 (-1 × 2^53 × 2^971)。在这个集合中取最接近x且可以表示的值。如果存在两个相同接近x的值则取具有偶有效数的那个。为了配合这个模式,两个附加数字2^1024和2^-1024被认为具有偶有效数。最后,如果2^1024被选择,用 +∞替换它。如果2^-1024被选择,用 -∞替换它。如果+0被选择,当且仅当x小于0时,用-0替换它。所有其他的值不变。最后的结果就是x的数值。(这个过程也符合 IEEE 754-2008中的就近舍入,选择偶数(round to nearest, ties to even))。

6.1.7 对象类型

一个对象在逻辑上是属性的集合。每个属性不是数据属性就是存取器属性:

一个数据属性(property)包含一个键,其与一个ECMAScript 语言值关联和一些
布尔属性(attribute)。

一个访问器属性包含一个键,其和一个或两个存取器函数关联和一些布尔属性。存取器函数用来存储或检索一个和属性关联的ECMAScript语言值。

属性被键标识。一个属性的键可以是一个ECMAScript字符串或一个符号(Symbol)。所有字符串和符号,包含空字符串都是有效的键。属性名是类型为字符串的键。

如果一个整数索引作为键的字符串,这个数字将是一个数字字符串。它的值大于等于+0,小于等于2^53-1。一个数组的索引是一个整数,它的取值为大于等于+0,小于等于2^32-1。

属性键用来访问属性和它们的值。由两种访问属性的方式:get和set,分别负责值的检索和设置。通过get和set可访问的属性包括自身的属性(这是对象本身的一部分),和与其他可访问对象间的属性继承关系继承来的属性。继承的属性可能它本身的或是继承而来的属性。对象的每一个自有属性一定都有一个和其他自有属性不重复的键。

所有在逻辑上是属性集合。但是对象有多种形式,它们在访问和修改它们属性的语义上是不同的。普通对象(Ordinary object)是最常见的对象形式,有默认的对象语义。外来对象(exotic object)具有对象的任何形式,它们的属性语义在任何方面都是与默认语义不同的。

6.1.7.1 属性(property)的元属性(attribute)

元属性(attribute)在这篇手册中被用来定义和解释对象属性的状态。一个被关联了键的数据属性具有下面表格中的元属性。


表格2

一个被关联了键的访问器属性具有下面表格中的元属性。


表格3

如果属性的元属性的初始值没有被这个手册明确定义,那么下面定义了这些默认值:


表格4

6.1.7.2 对象内部方法和内部槽

当前关于对象的语义,在ECMAScript中通过叫做内部方法的算法做出规定。每一个对象是一个ECMAScript引擎,被和一些内部方法关联,这定义了对象的运行时行为。这些内部方法不是ECMAScript语言的一部分。这篇规范定义了它们纯粹是为了表明意图。不论如何,一个ECMAScript实现中的每一个对象必须遵照与它关联的内部方法所指定的方式运转。(这)实现的确切方式是由(具体的ECMAScript)实现决定的。

内部方法名时多样的。这表示当一个通用的内部方法名在它们身上执行时不同的对象值可能表现出不同的算法。内部方法执行时所处的对象被称作执的目标。如果,在运行时,算法的实现尝试使用一个对象不支持的内部方法,一个TypeError一场将被抛出。

内部槽详单与内部状态。它们被和对象关联,并且被一些ECMAScript规范的算法所使用。内部槽不是对象属性并且它们无法继承。根据特殊的内部槽定义,这些状态可能由任何ECMAScript语言类型或者特殊的ECMAScript规格类型值所组成。除非显式指定,否则内部槽在创建对象时被分配并且不能被动态添加到对象。除非显式指定,内部槽的初始值时undefined。这篇规范中的一些算法创建具有内部槽的算法。然而,ECMAScript语言没有提供直接访问对象内部槽的方式。

这篇规范中内部方法和内部槽被标识在双中括号中[[]]。

表格5总结了这篇规范使用的基本的内部方法,它们适用于ECMAScript代码对所有对象的创建和操作。每个对象必须具有实现这些基本内部方法的算法。然而,所有的对象对这些方法的实现不一定时相同的代码。

表格5的签名列和其他类似的表格描述了每一个内部方法的调用模式。调用模式总是包含一个在括号中的带有描述性质的参数名列表。如果一个参数名和一个ECMAScript类型名相同,那么这个名字表示参数值应该具有这个类型。如果一个内部方法明确返回一个值,它的参数列表后会跟着一个→符号,并跟着返回值的类型名。签名中的类型名对应本节的内容,并且额外包括:”any”表示值可能是属于任何ECMAScript语言类型。一个内部方法暗中返回一个完成记录(Completion Record)。除了参数之外,一个内部方法总是有权访问调用这个方法的目标(对象)。


表格5

表格6总结了函数对象的附加基本内部方法。一个函数对象是一个支持[[Call]]内部方法的对象。一个构造器(也被称为构造函数)是一个支持[[Construct]]内部方法的函数对象。


表格6

普通对象和标准外来对象的基本内部方法语义在第9节规范(不在这篇文章中)。如果任何规范的发i部队向的内部方法使用没有被(ECMAScript)实现支持,那么这个用法一定要抛出一个TypeError异常。

6.1.7.3 基本内部方法的不变性
ECMAScript引擎对象的内部方法必须遵守下面规范出的不变性(规则)。这篇规范中的普通ECMAScript对象和所有的标准外来对象要坚持这些不变性(规则)。ECMAScript代理对象(ECMAScript Proxy object)依靠在运行时[[ProxyHandler]]对象的陷阱触发结果来坚持这些不变性(规则)。

任何提供外来对象的实现也必须对这些对象坚持这些不变性(规则)。违反这些不变性(规则)可能导致ECMAScript代码具有不可预知的行为并且产生安全问题。无论如何对这些不变性(规则)的违背一定不要带来内存安全问题。

在任何实现中一定不要允许这些不变性(规则)被任何形式的规避。例如通过提供对基本内部方法的功能的修改接口而不强制应用这些不变性(规则)。

定义:

内部方法的目标是这个内部方法调用所在的对象。

如果一个对象的[[IsExtensible]]内部方法返回了false或从[[PreventExtension]]返回true,它就是不可扩展的(non-extensible )。

如果一个属性不是一个不可扩展对象的自有属性,那么这个属性是一个不存在的属性(non-existent property)。

所有对相同值(SameValue)的判断依据相同值算法(不在本文中,参照http://www.ecma-international.org/ecma-262/7.0/index.html#sec-samevalue)。

[[GetPrototypeOf]]()返回值类型必须是Object或Null。如果目标是不可扩展的,并且[[GetPrototypeOf]]返回值v,那么之后任何对[[GetPrototypeOf]]的调用必须返回相同值v。注解:一个对象的原型链必须具有有限长度(就是说,从任何对象开始,递归的在其结果上调用[[GetPrototypeOf]]内部方法,最后会导致返回null)。然而,当原型链包含任何不使用[[GetPrototypeOf]]的普通对象定义的外来对象时,这个要求并不是一个对象级的不变性(规则)。例如一个环形原型链在访问对象原型时上可能导致无限循环。
[[SetPrototypeOf]] (V)返回值类型必须是布尔。如果目标是不可扩展的,[[SetPrototypeOf]]一定返回false,除非V是目标的[[GetPrototypeOf]]值。
[[IsExtensible]] ( )返回值类型必须是布尔。如果[[IsExtensible]]返回false,之后在目标上的[[IsExtensible]]调用必须返回false
[[PreventExtensions]] ( )返回值类型必须是布尔。如果[[PreventExtensions]]返回true,之后在目标上的[[IsExtensible]]调用必须返回false,并且目标现在被认为是不可扩展的。
[[GetOwnProperty]] (P)返回值类型必须是属性描述符或Undefined。如果返回类型是属性描述符,返回值必须是一个完整的属性描述符。如果属性P被Desc描述为一个数据属性即Desc.[[Value]]等于v并且Desc.[[Writable]] 和 Desc.[[Configurable]]都是false,那么之后对所有[[GetOwnProperty]] ( P )调用的返回值都必须是Desc.[[Value]]的相同值。如果P的元属性除了[[Writable]]可能在一段时间里改变或者如果属性可能消失,那额P的[[Configurable]]元属性必须为true。如果[[Writable]]元属性可能从false变为true,那么[[Configurable]]元属性必须为true。如果目标是不可扩展的并且P是不存在的,那么所有未来在目标上对 [[GetOwnProperty]] (P)的调用中P都必须是不存在的(例如[[GetOwnProperty]] (P)必须返回undefined)。注解:作为第三条不变性(规则)的影响,如果一个属性是一个数据属性并且它可能返回在之后返回不同的值,那么 Desc.[[Writable]] 和 Desc.[[Configurable]]元属性必须为true,即使没有其他内部方法没有机制去改变这个值。
[[DefineOwnProperty]] (P, Desc)返回值类型必须是布尔。如果P之前是目标不可配置的(non-configurable)自有属性,那么[[DefineOwnProperty]]必须返回false,除非下列情况之一成立:1.P是一个不可配置的,可写的自有数据属性。一个不可配置的,可写的数据属性可以被改编为不可配置的,不可写的数据属性。2.Desc中的所有元属性和P的元属性具有相同值。如果目标是不可扩展的并且P是不存在的自有属性,那么[[DefineOwnProperty]] (P, Desc) 一定返回false。就是说,一个不可扩展的目标对象不能被新属性扩展。
[[HasProperty]] ( P )返回值类型必须是布尔。如果P之前是目标的不可配置的数据或访问器属性,[[HasProperty]]一定返回true
[[Get]] (P, Receiver)如果目标上P是之前是不可配置的,不可写的属性,并且值为v,那么[[Get]]必须返回同样的值。如果在目标上P之前是一个不可配置的自有访问器属性,且它的[[Get]]元属性没有被定义,那么[[Get]]必须返回undefined。
[[Set]] ( P, V, Receiver)返回值类型必须是布尔。如果在目标上P之前是不可配置的,不可写的自有数据属性,那么[[Set]]必须返回false除非V和P的[[Value]]元属性是相同值。如果在目标上P之前是不可配置的自有访问器属性,它的[[Set]]元属性没有被定义,那么[[Set]]必须被返回false
[[Delete]] ( P )返回值类型必须是布尔。如果在目标上P之前是不可配置的自有数据属性,那么[[Delete]]必须返回false
[[OwnPropertyKeys]] ( )返回值必须是一个列表(List)。返回列表的每一个元素必须是String或Symbol。返回列表至少要包含之前是非可配置的所有自有元素的键。如果对象是不可扩展的,返回的列表仅仅包含对象上全部可以通过[[GetOwnProperty]]获得的属性的键。
[[Construct]] ( )返回值必须是对象。

6.1.7.4 众所周知的固有对象

广为人知的固有对象就是被这篇规范所引用的内建对象,它们经常具有特定领域中的概念。除非另有说明,在每一个领域(realm,不在本文档描述,见 http://www.ecma-international.org/ecma-262/7.0/index.html#realm )每一个固有对象对应一些相似的对象。

在这篇规范中一个类似%name%的引用表示和领域关联的固有对象所对应的名字。如何确定当前领域和它的固有对象在8.3节中描述(见,http://www.ecma-international.org/ecma-262/7.0/index.html#sec-execution-contexts )。广为人知的股有对象见表7。

表格7

原创粉丝点击