ECMAScript 整理(上)
一、什么是ECMAScript(以下简称ECMA),JAVAScript与ECMA的关系
JavaScript是一门面向对象的动态语言。静态语言(像Java,C),是需要编译器编译后执行的,而JavaScript是由解释器直接解析运行的。这种解释器即是Javascript引擎,比如Chrome的V8。
Javascript的运行环境,是由宿主环境和执行期环境构成的。宿主环境是外壳程序生成的(这里以Web浏览器为例),执行期环境则是由这个引擎生成的。
这两个环境分别是干嘛的呢?因为JavaScript是一个脚本语言,它本身不提供IO接口,没有与系统和外界通信的能力,所以这些事情都交给宿主环境来完成。
比如window对象的alert方法,document.write()等。而Javascript创建执行环境,生成内置对象这些它自己的事儿,就在执行期环境中完成。
ECMA就是用来规范Javascript引擎的。
ECMA是一个标准,它制定了脚本语言的一套规则。JavaScript就是依据这套规则实现的,可以看作ECMA的一个实例。
一个ECMA的实例必须提供并支持这套规则里所有的类(types),值(values),对象(objects),属性(properties),函数(functions),程序语法和语义。(ECMA也正是由这些东西组成的)。
p.s .以下是对下文将用的ECMA术语的一个说明
- type 类型:一组数据值(它的成员即是value,type 和 value 的关系可以用数学里的集合来理解)
- primitive value 原始值:原始类型的成员
- object 对象:Object类型的成员
- constructor 构造函数:它是一个内置对象Function,用来初始化对象的
- prototype 原型:它是一个对象,为其它对象提共享属性
- native object 本地对象:由ECMA实现的,非宿主环境提供的对象。
- built-in object 内置对象:ECMA提供的,独立于宿主环境的对象。
- host object 宿主对象:宿主环境提供的对象。
- undefined value 未定义值:当一个变量声明时没有赋值,则默认为此值。
- Undefined Type 未定义类型:即包含未定义值的这个集合。
- function 函数:对象类型的成员,是内置对象Function的实例,可以作为子程序调用。
- method 方法:作为一个属性的value的function
- built-in function 内置函数:为function的内置对象,例如parestInt()
- property 属性:一个name对应一个value,类似map的形式
- attribute:内部值,定义属性的特征。(不知道用中文怎么表达,我叫它属性的属性 = 。=)
- own property 和 inheirted property:自有属性和继承属性。
二、一切皆对象
语言 = 数据结构 + 算法。首先对ECMA的数据结构做一个了解。
Javascript是一门高度抽象的面向对象的语言,一切皆对象。
1、什么是对象?(注意这里的对象是object,不是内置类型Object,注意区分大小写)
一个ECMA的程序是由许多可以互相通信的object组成。每个object是由一系列的属性(property)组成。
每个property可以看成一个容器,这个容器也具有一些属性,这些属性叫作attribute。
这个容器里存放的东西可以是其它的object,原始值(primitive value)或函数(function)。
每个object是ECMA的内置类型(built-in type)Object的成员。
每个primitive value是ECMA的内置类型Undefined,Null,String,Number,Boolean之一的成员。(以上即是ECMA语言的类型,ECMA还有另外一些特定类型)
function是个特殊的object,它是一个可调用的object。和一个object的属性联系在一起的function,我们叫它方法(method)。
ECMA已经定义了许多object供使用,这些定义好的object被称为内置对象(built-in object)。其中包括全局对象(global object)和异常对象(error object)。
全局对象包括:Object , Function , Array , String , Boolean ,Number , Math ,Date , RegExp , JSON
异常对象包括:Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError.
(这里又出现了一个Object ,这个全局对象Object是ECMA定义好的object,是内置类型Object的成员)
(对于String,Number,Boolean。以Number为例,对var a = 1这样的代码,返回值为原始值Number value。对 var a = new Number(1),返回值则为Number对象)
2、如何创建对象
ECMA中规定创建对象有两种方法:字面量(literal notation),构造函数(constructor)。
比如以下代码:

在Chrome的console中进行查看

定义了一个未赋值的a变量,它的返回值是原始值undefined。
用字面量创建对象的方法定义了一个b,并给它传递了两个属性。(似乎这就是JSON的样子?其实我们平常所说的JSON,是指对象字面量。即Object{}这样的形式。ECMA另外规定了JSON对象,和这里的字面量不是一回事)。
c是用构造函数创建的对象。构造函数是创建一个实例时用到的函数,表现形式就是 new 运算符。我们new了一个Object的实例 c。
P.s 关于字面量的解释

Q:全局对象Object ,String , Boolean ,Number 和内置类型是什么关系,如何区别。
Q:全局对象 Function和 function ?function 是Function的实例。
三、constructor 和 prototype
每个函数都有一个prototype的属性,当我们以这个函数为构造函数创建实例时(即用new的形式),创建出来的这个对象是没有prototype的属性的。
以下代码为例:

在console里进行调试

cf 拥有一个prototype的属性,这个属性就叫做原型。这个原型本身是一个对象cf{},我们叫它原型对象。
cf 的原型对象有一个constructor的属性,它就是构造函数。我们可以看到,这个构造函数是cf本身。(当然它还有一些别的属性。)
cf1 作为 cf 的实例,它拥有了cf.prototype里的所有属性。把cf1展开看一下:

可以看到cf1 有一个隐式属性proto,这个属性是无法通过ECMA语句访问到的。它指向了cf.prototype这个原型对象,这就是原性链。
原型对象本身作为ECMA内置对象Object的一个实例,它也有proto,指向的是Object.prototype,这就构成了一个链表的结构。
这个链表就决定了在查找属性时的顺序。例如ECMA在查找 cf1.p1时,会先查找它本身,若没有p1这个属性,再沿着_proto_找。
在这里 new 操作符所做的事情,可以分为以下:
- 建立一个新对象cf1 var cf1 = cf{ };
- 将cf1的_proto_指向原型对象 cf1._proto = cf.prototype
- 将cf1作为this的参数,调用构造函数cf。 cf.call(cf1)
- 返回这个新对象
四、严格模式
严格模式是另一种运行模式。进入方法有两种,在全局代码的第一行或者在函数体内部第一行书行 use strict,作用域也随之改变。
五、记法约定
在深入学习ECMA前,先了解一下第5章-记法约定。有助于在阅读过程中更好的理解。
1、上下文无关文法
可以这么理解,自然语言是上下文有关的,计算机语言是上下文无关的。下面解释一下什么是上下文无关。
首先,了解一下什么是产生式(productions)。在编程语言中, a 是一个变量的表达式, a+b是表达两个变量相加的表达式,(a+b)是一个括号表达式,这些表达式即为产生式。我们把它记为E。计算机语言推导一个表达式的过程,即是从右向左或从左向右把E展开的过程。如a+(b+c),从左向右的展开过程为E→a+E→a+(E)→a+(b+E)→a+(b+c)。上下文无关为法,即产生式可以无条件展开。
2、终结符与非终结符
每个产生式的左侧是由一个非终结符组成,右侧由0或多个非终究符和终结符有序排列组成。所谓终结符即是语言中的最小元素,不能被分割。在ECMA中,除空白和注释之外的输入元素构成了终结符,它们被称为tokens,这些tokens包括保留字、标识符、字面量及标点符号。另外,行终结符是输入元素,但不是tokens,它是用来协助自动加分号机制的。
词法文法和字符串文法的终结符,以及一些语法文法的终结符用字体fixed with显示。 非终结符用italic表示。
也就是说,每个斜体都可以由数个非斜体取代,这就是终结符与非终结符的区别。
3、冒号分隔符
两个冒号 :: 用来分割词法和正则的文法产生式(它们有部分是共用的)
三个冒号 ::: 用来分割数字字符串的文法产生式
一个冒号 : 用来分割语法文法产生式
4、语法文法
一个Unicode字符流被解析为ECMA程序,首先,反复通过词法文法的应用,把字符流解析为一个输入元素流.然后,这个输入元素流再被一个语法文法的应用所解析.如果其中的标记(tokens),无法和余下的其他标记(tokens)一起,被解析为单一的,非终结的,Program 目标符实例,则这个程序有语法错误.
5、JSON文法
JSON文法包括JSON词法文法和语法文法两部分。
其中词法文法部分,是用于把字符序列转换成tokens的,并且类似于ECMAScript的部分词法文法。 JSON语法文法,是用于描述如何使用通过词法文法得到的tokens,来组成符合语法的 JSON 对象的. JSON词法文法产生式,是以两个冒号 "::"作为其特征以及分隔性的符号。JSON词法文法直接使用了一些ECMA词法文法的产生式,作为其产生式。
而JSON语法文法,基本与ECMA语法文法的某一部分相类同. JSON语法文法的产生式,是以 一个冒号":",作为其特征以及分隔符号的.
Q: 什么是文法产生式啊。。后面的例子神马的完全看不懂啊。。。