ECMAScript 整理(上)

阅读数:881 发布时间:2016-09-28 21:33:33

作者:w4gyc 标签: ECMAScript

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术语的一个说明

二、一切皆对象

语言 = 数据结构 + 算法。首先对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)。 比如以下代码:

img1

在Chrome的console中进行查看

img2

定义了一个未赋值的a变量,它的返回值是原始值undefined。

用字面量创建对象的方法定义了一个b,并给它传递了两个属性。(似乎这就是JSON的样子?其实我们平常所说的JSON,是指对象字面量。即Object{}这样的形式。ECMA另外规定了JSON对象,和这里的字面量不是一回事)。

c是用构造函数创建的对象。构造函数是创建一个实例时用到的函数,表现形式就是 new 运算符。我们new了一个Object的实例 c。

P.s 关于字面量的解释

img3

Q:全局对象Object ,String , Boolean ,Number 和内置类型是什么关系,如何区别。

Q:全局对象 Function和 function ?function 是Function的实例。

三、constructor 和 prototype

每个函数都有一个prototype的属性,当我们以这个函数为构造函数创建实例时(即用new的形式),创建出来的这个对象是没有prototype的属性的。

以下代码为例:

img4

在console里进行调试

img5

cf 拥有一个prototype的属性,这个属性就叫做原型。这个原型本身是一个对象cf{},我们叫它原型对象。

cf 的原型对象有一个constructor的属性,它就是构造函数。我们可以看到,这个构造函数是cf本身。(当然它还有一些别的属性。)

cf1 作为 cf 的实例,它拥有了cf.prototype里的所有属性。把cf1展开看一下:

img6

可以看到cf1 有一个隐式属性proto,这个属性是无法通过ECMA语句访问到的。它指向了cf.prototype这个原型对象,这就是原性链。

原型对象本身作为ECMA内置对象Object的一个实例,它也有proto,指向的是Object.prototype,这就构成了一个链表的结构。

这个链表就决定了在查找属性时的顺序。例如ECMA在查找 cf1.p1时,会先查找它本身,若没有p1这个属性,再沿着_proto_找。

在这里 new 操作符所做的事情,可以分为以下:

  1. 建立一个新对象cf1 var cf1 = cf{ };
  2. 将cf1的_proto_指向原型对象 cf1._proto = cf.prototype
  3. 将cf1作为this的参数,调用构造函数cf。 cf.call(cf1)
  4. 返回这个新对象

四、严格模式

严格模式是另一种运行模式。进入方法有两种,在全局代码的第一行或者在函数体内部第一行书行 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: 什么是文法产生式啊。。后面的例子神马的完全看不懂啊。。。

相关文章推荐: