2008-03-15

JavaScript与Rhino

声明:引用或复制该文章必须注明作者与出处。
声明:任何使用该文档内容必须经过作者的同意。
声明:请点击广告,支持作者原创。



1  概述

ECMAScirpt是个基于对象的语言,目的是在宿主环境中进行计算和维护可计算的对象。Script是编程语言,用来维护,定制和已经存在的系统的机制。在这样系统中,已经通过用户界面提供了有用的功能,而script是一种机制,用来暴露该功能,并且能够编程控制,那么已经存在的系统就称为宿主环境(host environment)Script语言目的是让专业和非专业人员能够使用,因此语言没有那么严格。

1.1  WebScripting

浏览器提供了ECMAScript的宿主环境,用来C/S计算,提供了窗口、菜单、对话框、文本区、链接、框架,历史,cookie,输入/输出等对象。宿主环境提供一种手段来将脚步代码跟事件联系起来,如焦点改变,页面和图片装载,卸载,错误和退出,选择,窗体提交和鼠标动作。脚本代码是在html代码中,而显示页是文本和图片的综合体。

1.2  LanguageOverview

ECMAScript是基于对象的:由对象提供基本语言和宿主机制。ECMAScript程序是一组通信对象的集合。ECMAScriptObjectproperties的无序集合,每个properties可以多个attributeProperties是容器,可以拥有其他对象,primitive valuesmethodsPrimitive value是下面内置类型之一:UndefinedNullBooleanNumberStringObject是内置类型Object,而method是通过property关联的functionECMAScript定义一组内置对象。内置对象包括GlobalObjectFunctionArray,String,Boolean,Number,Math,Date,RegExp和各种Error对象。

ECMAScript定义了内置的操作符。

1.3  Object

ECMAScript没有class的概念因此构造一个对象的时候不是像java一样构造对象也没有单独的构造体方法。

ConstructorMethod的一种。

ECMAScript支持prototype-based的继承。

  java中,继承是扩展原有的方法。JavaScript中,方法只是对象的其中一个属性,例如:  squart:function(){return true}.因此,如果要扩展squart属性的话,如何扩展呢?javascript应该没有提供扩展原来方法的功能,没有super.squart,只能够重新定义。

java中,继承是通过extends Object来实现的。但javascript却没有extends的概念。Javascript中对象是由一组属性构成。属性可以基本类型,也可以是Function类型。

1.4  定义

1.4.1  Constructor

构造体,构造体当然是Function对象了,目的是创建和初始化对象。

每个constructor都有相关的prototype对象,用来实现继承和共享对象。

这表明javascript的构造体不同于java中的表示。Java中的构造体表示是:

Public  Point(){

}

javascript的构造体更像是Delphi中的表示:

procedure construct(){

}

因为每个对象都有构造体,最基本的构造体就称为prototype

1.4.2  Prototype

每样的东西都要原来的最基本的样子。例如,所有的java的类都扩展Object,那么Object类里面的所有的东西都是其最基本的样子。

Prototype是一个对象,用来实现结构,状态和行为的继承。

constructor创建一个对象,该对象就隐含了引用构造体相关的原型。

构造体关联原型用程序constructor.prototype表示。添加到原型中的属性是共享的。

Prototype类似java中的基本类ObjectConstructor.prototype相当于super.constructor

1.4.3  NativeObject

独立于宿主环境的对象就是本地对象。

1.4.4  Built-inObject

内置对象,由ECMA规范定义的对象。

ECMAScriptattribute的定义是下面几种:readonly,dontenum,dontdelete,internal相当于java中的修饰符。

1.4.5  Object

注意ECMAScript规范对Object的定义,不同于其他语言:

Object – an unordered collection of properties每个propertynamevalue和一组attributes构成。在其他语言系统中,例如Delphi,它明确定义一个组件是由property/event/method构成的。在java中,没有单独定义event。它把eventmethod放在一起。Delphi是直接面向GUI的,而java不是。每个对象必须实现prototypeclass属性,和get/put/canPut/hasProperty/delete/defaultValue方法。[[prototype]]property的值必须是object或者nullprototype链必须有有限的长度,也就是从某个对象开始,递归访问prototype属性,最终会访问到null值。

1.4.6  内在方法

下面方法并非是javascript的语言中定义,而仅仅是表述而已。

      object.get(propertyName)

(1)      如果object没有propertyName,跳到4

(2)      读取property对应的propertyValue

(3)      返回结果2

(4)      如果objectprototypenull,返回undefined

(5)      调用prototypeget(propertyName)

(6)      返回结果5

      object.put(propertName,propertyValue)

(1)   调用canPut(propertyName)

(2)   如果1返回false,返回。

(3)   如果object没有propertyName,跳到6

(4)   设置property的值为propertyValue,其attribute没有改变。

(5)   返回。

(6)   创建一个名称为propertyNameproperty,并且设置值为propertyValue,设置empty attribute

(7)   返回。

      canPut(propertName)

      hasProperty(propertyName)

      delete(propertyName)

      defaultValue

1.4.7  Reference类型

1.5  Execution Contexts执行上下文

1.5.1  Function Objects函数对象

有两种类型的Function Objects

      编程函数由js文件中定义,通过FunctionDeclaration或者FunctionExpression或者使用内置的Function对象作为构造体。

即:

function xxx(){

  return true;

}

 

function (){ return true;}

 

new Function(“”,”return true”);

      内置函数,如parseIntMath.exp等,由语言解析器提供。

1.5.2  可执行代码的类型

3种类型:

2  Rhino

Rhinojavascript的解析引擎。

2.1  ContextFactory

      提供singleton的方式获取ContextFactory

      包含了一个事件监听接口。

      包含对事件监听器的添加和删除管理。

      提供了Context.enter/exit的方法。

      提供几个protected方法,用来扩展ContextFactoryMakeContext()/hasFeature()/observeInstructionCount()/onContextCreated/onContextReleased

      定义一个变量sealed,如果设置sealedtrue的话,则不能添加删除事件监听器。

2.2  Context

      提供Context的几个静态方法:获取当前的Contextenter/exit的方法。

      提供seal/unseal操作,每个seal都有key

      提供languageVersion语言版本、实现版本、LocaleErrorReporter和相关的report的便利方法。

      提供PropertyChangeListener的事件管理。

      提供Call的静态方法。

      提供initStandObjects()的静态方法。

      提供evaluateString/evaluateReader解析方法。

      提供compileString/compileReader/compileFunction编译方法。

      提供decompileScript/decompileFunction/decompileFunctionBody反编译方法。

      提供newObject/newArray创建方法。

      提供将对象转变为基本类型的方法toBoolean/toNumber/toString/toObject

      提供编译优化等级,最大解析堆栈深度,安全控制器,InstructionObserverThreshold等的读取和设置。

      提供key-value存放到ThreadLocal的添加删除保存方法getThreadLocal/putThreadLocal/removeThreadLocal

2.3  ScriptRuntime

 

2.4  initStandardObjects(Context cx, ScriptableObject scope, boolean sealed)

如果scope为空,就新建一个NativeObject来作为全局对象。如果设置了scope了,则用其来作为全局对象。

然后就将其存放在关联表中,用LIBRARY_SCOPE_KEY作为关键字,用新建的NativeObject作为值,存放在新建的NativeObject中。

2.5  ScriptableObject

Javascript对象的基本类。

      定义了四种属性(attribute)empty/readonly/dontenum/permanent.

      attribute提供了get/set的方法。Attribute是用常量定义的。

      property提供了has/get/put/delete的方法,propertypropertyNamepropertyValue构成的。

      ScriptableObject的构造体由parentscopeprototype构成,提供了get/set父亲scopeprototype的方法。

      提供getDefaultValue()方法。

      提供defineClass静态方法:defineClass是将java编写的类转变为javascript对象。不过编写java类要遵循一定的规则。其规则为:

      函数要用jsFunction_jsStaticFunction_表示.

      Get/set要用jsGet_jsSet_表示。

      构造体要用jsConstructor表示。

      提供defineProperty静态方法:将propertyNamepropertyValueattributes设置到javascript对象中。提供多种定义property的方法:

可以根据propertyName/propertyValue/attributes设置。

可以根据 propertyName/JavaClass/attributes设置。

可以根据propertyName/delegateTo/getter/setter/attributes设置。

函数是Javascript对象中的一个特殊的propertyNamedefineFunctionPoperties就是根据functionName/function/attributes保存到property中的。

PropertyScriptableObject中是由Slot类表示的,每个slot包含propertyID/propertyName/propertyValue/attributes很明显,property是用List来管理的。

      提供获取prototype的静态方法:getObjectPrototype/getFunctionPrototype/getClassPrototype.

      提供获取顶层scope的方法getTopLevelScope

      提供下面静态方法:读取propertyValuehasPropertyputProperty,deleteProperty的静态方法。

      提供callMethod静态方法,callMethod要求输入javascript对象的方法名称和参数。实现原理是查找javascript对象的方法名对应的函数。然后进行fun.call来执行,得到函数执行的结果。

      associateValue(key,val

评论
发表评论

您还没有登录,请登录后发表评论