ECMA-262简述
ECMAScript语言概述
ECMAScript对象概述(原型链Prototype Chain)
ECMA-262主要术语
ECMAScript执行环境(作用域链Scope Chain,闭包机制)
ECMAScript函数(new原理)
ECMAScript内部属性(参考)
ECMAScript执行环境作用域链图示
ECMA-262参考资料
ECMA-262简述
ECMA(European Computer Manufacturers Association)
ECMA-262标准的最初的版本是基于Brendan Eich创造的JavaScript语言来制定的,它是ECMAScript脚本语言的规范及标 准。该标准在1998年4 月通过快速通道提交到ISO/IEC JTC 1并被采纳为国际标准ISO/IEC 16262,所以之后一直简称为 ECMA-262,该标准发展到现在已经到了第5版。
所有遵循ECMA-262标准实现的脚本都可以称之为ECMAScript,如JavaScript, JScript, ActionScript等等。
注意:ECMA-262是从ECMAScript脚本引擎实现的角度去描述的。
我们目前所使用的大部分浏览器中的脚本引擎多数都是基于ECMA-262标准第3版的实现,参见下图:
ECMAScript语言概述
ECMAScript最初的设计是一种网页脚本语言。
脚本语言是一种编程语言,可用来操作、自定义、自动化现有系统中的设备。
在某些系统中,一些可用的功能是可以通过用户接口来使用的。而脚本语言,就是将这些功能暴露给编程人员进行控制的机制。这样的系统,我们可以说,它们为我 们提供了一个运行脚本语言的宿主环境。脚本语言是专门给专业和非专业的编程人员使用的,为了适应非专业的程序员,有些方面多少有些不太严格。
脚本语言与宿主环境是两个不同的主体,比如,浏览器就为ECMAScript提供了一个宿主环境,BOM和DOM则都是浏览器提供的功能,而各种基于 ECMA262实现的脚本语言,如JavaScript,Jscript等,都可以为我们提供对BOM和DOM的操作方法。因为宿主环境的不同,它们提供 的功能也不尽相同,这也是我们知道的,不同的浏览器中会有不同的BOM和DOM的属性和方法。
ECMAScript是基于对象(object-based)的编程语言,在宿主环境中执行计算或操作对象。ECMAScript程序就是一个对象间交互 通信的聚合。 在ECMAScript中,“对象”(object)的properties是一个无序的集合,properties 是一个容器,可以包 含其他的对象,原始值(primitive values)或方法(methods)。
原始值属于下列“内置类型”(built-in types)中的一员:Undefined, Null, Boolean, Number和String,“对象 ”则是内置类型:Object,“方法”是一个透过property关联到对象的函数。
ECMAScript定义了“内置对象”(built-in objects),以使ECMAScript实体更为完善。这些内置对象包括:Global 对象,Object对象, Function对象,Array对象,String对象,Boolean对象,Number对象,Math对象,Date对 象, RegExp对象和错误对 象: Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError。
ECMAScript还定义了“内置操作符”或者说是“函数”或“方法”。ECMAScript操作符包括了各种一元运算符、乘除运算符、加减法运算符、位移运算符、关系运算符、相等运算符、二元运算符、二元逻辑运算符、分配运算符和逗号运算符。
ECMAScript的语法类似Java的语法。ECMAScript语法宽松是为了使它能够成为更容易使用的脚本语言。比如,变量不需要申明类型也不需要为properties指定类型,函数定义也可以不需要出现在它们的调用语句之前。
ECMAScript对象概述
ECMAScript没有像C++,Smalltalk,Java等语言中的真正的类,但是它支持构造器(constructors)。它在代码执行时创 建对象,为对象分配内存并初始化它们全部或部分初始值和properties。所有的构造器都是对象,但不是所有对象都是构造器。每个构造器都有一个 Prototype属性用于实现基于原型的继承(prototype-based inheritance)和属性共享 (shared properties)。
对象在对构造器使用new表达式时被创建,比如,new String(“A String”)创建了一个新的字符串对象。不用new表达式直接去调用一 个构造器,其结果将依赖于这个构造器的具体实现,如,String("A String") 产生一个原始值String,而不是一个对象。
ECMAScript支持基于原型的继承。所有构造器都有一个相关联的原型,所有由构造器创建的对象都隐含一个指向到该原型的引用(称为对象原型),此 外,一个原型可能有一个非空的、隐含的引用,指向到它的原型,所以,这又被称为是:原型链(prototype chain)
当一个引用来自一个对象时,它会去该对象和它的原型(链)中查找与该property同名的属性,换句话说,会先直接从该对象中检测是否存在这个同名的引用,如果有则返回,否则再从该对象的原型(链)中去检测是否存在该引用。(DEMO)
DEMO:
<script type="text/javascript">
Object.prototype.hi = function(){
alert('object.prototype.hi');
};
Object.prototype.greetings = function(){
alert('object.prototype.greetings');
};
Function.prototype.greetings = function(){
alert('function.prototype.greetings');
};
var CF = function(){};
CF.prototype.hello = function(){
alert('CF.prototype.hello');
};
CF.prototype.bye = function(){
alert('CF.prototype.bye');
};
var o = new CF();
o.hello = function(){alert('o.hello');};
o.hello();
o.bye();
o.hi();
o.greetings();
CF.hi();
CF.greetings();
</script>
在基于类的面向对象语言里,通常,状态由实例持有,方法由类持有,继承只有结构和行为。在ECMAScript中,状态和方法由对象持有,结构、行为和状态都可以被继承。
对象通常都不会直接包含那些由原型包含共享的属性和值。描述见下图:
CF是一个构造函数(同时也是一个对象)。通过对它进行new表达式创建了5个实例对象:cf1,cf2,cf3,cf4,cf5。每个实例对象都包含有q1 和q2两个属性。(DEMO)
例如,Cfp是cf3的原型(虚线,表示隐含的原型关系),构造函数CF自己有两个属性P1和P2,它们 对 Cfp,cf1,cf2,cf3,cf4,cf5都不可见。Cfp的属性CFP1对cf1,cf2,cf3,cf4,cf5可见(但不包括CF),还 有那些在Cfp的隐含的原型链中找到的 property name(非q1,q2或者CFP1的其他属性)。注意,CF和Cfp之间并非隐含的原型联 系。
与基于类的对象语言不同,ECMAScript对象的属性可以通过给对象赋值的方式动态地添加到对象上,意思就是,构造函数不需要一个个地为那些由它构造 出的对象赋值,如上图,只要为CFp添加一个属性值,即可使得由CF构造出的所有对象:cf1,cf2,cf3,cf4,cf5共享。
DEMO:
<script type="text/javascript">
var CF = function(){};
CF.p1 = 'p1';
CF.p2 = 'p2';
CF.prototype = {CFP1:'cfp1'};
var cf1 = new CF(),cf2 = new CF(),cf3 = new CF(),cf4 = new CF(),cf5 = new CF();
alert(cf1.p1+','+cf2.p2);//构造函数自身的属性对由它构造出的对象不可见
alert(CF.CFP1);//对CF不可见
alert(cf1.CFP1);//对CF构造的所有对象可见
cf3.__proto__.CFP2 = 'cfp2';//在构造函数原型上添加属性
//__proto__相当于从cf3到CF.prototype的隐含的原型关系,该属性是SpiderMonkey引擎的私有属性,仅限在SpiderMonkey引擎中访问
alert(cf1.CFP2);//即可对所有该构造函数构造的对象进行共享
</script>
ECMA-262主要术语
以下是ECMAScript中主要术语的非正式定义。
Type
数据值的集合
Primitive Value
原始值包括Undefined,Null,Boolean,Number,String这些类型成员。原始值是语言实现中底层可以直接表示的数据。
Object
每个对象都是Object类型的成员。它包含的所有属性成员,如原始值、对象或者函数,是一个无序的集合。对象属性成员放置的函数又被称为方法。
Constructor
构造器是一个函数对象,用来创建和初始化对象。每个构造器都有一个关联的原型对象用来实现属性成员的继承和共享。
Prototype
ECMAScript中的原型用来实现对象结构、状态和行为的继承。当一个构造器构造了一个对象,这个对象会隐含地引用到该构造器关联的原型去解析属性的 引用。构造器关联的原型可以通过程序表达式constructor.prototype 来引用。在某个共享对象的原型上添加的属性值,通过继承,可以被 所有其他对象共享。
Native Object
原生对象是由ECMAScript的实现提供的,独立于宿主环境。有些原生对像同时又是内置对象,其他的则可能会在执行一个 ECMAScript程序时产生。
Built-in Object
内置对象是由ECMAScript的实现提供的,独立于宿主环境,它们出现在ECMAScript程序开始执行的时候。所有的内置对象都是原生对象。
Host Object
宿主对象由为ECMAScript提供完整执行环境的宿主环境提供的。任何对象,不是原生对象,就是宿主对象。
Undefined Value
Undefined值是一个原始值,当一个变量没有被分配值的时候使用。
Undefined Type
Undefined类型只有一个值,undefined。
Null Value
Null值是一个原始值,它表示空的,没有的,或不存在的引用。
Null Type
Null类型有一个值,null。
Boolean Value
Boolean值是Boolean类型的成员,它只能是两个值中的一个,true或false。
Boolean Type
Boolean类型表示一个逻辑实体,由两个唯一值组成,一个是true,另一个是false。
Boolean Object
Boolean对象是Object类型的成员,它是内置对象Boolean的实例。意思是,一个Boolean对象是通过Boolean构造器的 new 表 达式创建,提供一个boolean参数。结果对象有一个隐含的(未命名)原型boolean。一个Boolean对象支配一个 Boolean值。
String Value
String值是String类型的成员,它是一个有限的有序的,0到16位无符号整数长度的值。注意:尽管每个值通常都表示一个单独的16位的UTF-16文本的单元,但该语言不会做出任何限制和要求当这个值不是16位无符号整数的情况时。
String Type
String类型是所有字符串值的集合。
String Object
String对象是Object类型的成员,它是内置对象String的实例。
Number Value
Number值是Number类型的成员,它是一个直接表示的数字。
Number Type
Number类型是表示数字的值的集合。在ECMAScript中,该集合表示IEEE754的64位双精度运算格式的值,包含一个特殊值"Not-a- Number"(NaN),正无穷大和负无穷大。
Number Object
Number对象是Object类型的成员,它是内置对象Number的实例。
Infinity
原始值Infinity表示一个正无穷大的数字,Number类型成员。
NaN
原始值NaN表示IEEE标准"Not-a-Number"值的集合,Number类型成员。