[领域]javascript hacking guide 第5部分

news/2024/7/3 5:58:05
2007年02月06日 11:49:00

mapJSObject的一个重要属性,存放一个对象的所有的属性的入口。要想了解map,就需要打开jsobj.h文件,看里面的定义。

struct JSObject {

JSObjectMap *map;

jsval *slots;

};

很自然的,我们还要找到JSObjectMap的定义,它也在jsobj.h文件中

struct JSObjectMap {

jsrefcount nrefs; /* count of all referencing objects */

JSObjectOps *ops; /* high level object operation vtable */

uint32 nslots; /* length of obj- vector */

uint32 freeslot; /* index of next free obj-

};

在这个定义中,最重要的信息隐含在注释中,第一个是对ops的注释,我们会看到ops其实是一个virtual table。这表示,对象的所有的属性名,都存放在这个vtable中;第2个信息是对nslots的注释,它提及obj- 其实是一个vector

这如同在告诉我们,我们在定义一个对象的属性时,属性的名称和类型等信息,会通过ops增加到属性表中,属性的值会对应放到slots这个vector中。例如:

var obj = new Object();

obj.a = 5;

那么"a"这个属性的类型是整型的,slots中增加了个新的值5。仔细看去,opsJSObjectOps这个结构体中,我们可以在jsapi.h中找到这个结构体的定义:

struct JSObjectOps {

/* Mandatory non-null function pointer members. */

JSNewObjectMapOp newObjectMap;

JSObjectMapOp destroyObjectMap;

JSLookupPropOp lookupProperty;

JSDefinePropOp defineProperty;

JSPropertyIdOp getProperty;

JSPropertyIdOp setProperty;

JSAttributesOp getAttributes;

JSAttributesOp setAttributes;

JSPropertyIdOp deleteProperty;

JSConvertOp defaultValue;

JSNewEnumerateOp enumerate;

JSCheckAccessIdOp checkAccess;

/* Optionally non-null members start here. */

JSObjectOp thisObject;

JSPropertyRefOp dropProperty;

JSNative call;

JSNative construct;

JSXDRObjectOp xdrObject;

JSHasInstanceOp hasInstance;

JSSetObjectSlotOp setProto;

JSSetObjectSlotOp setParent;

JSMarkOp mark;

JSFinalizeOp clear;

JSGetRequiredSlotOp getRequiredSlot;

JSSetRequiredSlotOp setRequiredSlot;

};

我们可以简单的浏览一下其中的函数指针名称,创建objectmap,定义属性,删除属性,给属性设置值或者获取属性值。。。。闭上眼睛想一想,这其中的函数指针是如此之多,所以一个对象的属性的类型判断(比如是整型还是String还是其他的)或者是属性名或者属性值的存放,都是通过预先定义好的指针函数来完成。

我们甚至可以用一个新的示意图来表示这一切:

我们可以这样去想,有一个table,里面存放对象的属性列表。根据ruby hacking guide的说法,我们可以想像,有一张大的表,存放所有的对象的属性,也可能每个对象有自己的属性表。但,这属于具体实现的范畴,我们只要明白每个对象有属于自己的属性表,对表格中的行或者列进行操作时,是由JSObjectOps这个结构体中的指针函数来完成的就可以了。

/*

* Share proto's map only if it has the same JSObjectOps, and only if

* proto's class has the same private and reserved slots as obj's map

* and class have. We assume that if prototype and object are of the

* same class, they always have the same number of computed reserved

* slots (returned via clasp-

* object classes must have the same (null or not) reserveSlots hook.

*/

if (proto &&

(map = proto-

((protoclasp = OBJ_GET_CLASS(cx, proto)) == clasp ||

(!((protoclasp-

(JSCLASS_HAS_PRIVATE |

(JSCLASS_RESERVED_SLOTS_MASK >> JSCLASS_RESERVED_SLOTS_SHIFT))) &&

protoclasp-

{

/*

* Default parent to the parent of the prototype, which was set from

* the parent of the prototype's constructor.

*/

if (!parent)

parent = OBJ_GET_PARENT(cx, proto);

/* Share the given prototype's map. */

obj-

/* Ensure that obj starts with the minimum slots for clasp. */

nslots = JS_INITIAL_NSLOTS;

} else {

/* Leave parent alone. Allocate a new map for obj. */

map = ops-

if (!map)

goto bad;

obj-

/* Let ops-

nslots = map-

}

Ok,我们在上回书说到有若干的判断条件,就是为了创建一个map,并设置为obj-的属性――不管是用parent的原型来创建,还是单独创建新的mapif 。。。else 部分),最终都是为了这个目的。

/* Allocate a slots vector, with a -1'st element telling its length. */

newslots = AllocSlots(cx, NULL, nslots);

if (!newslots) {

js_DropObjectMap(cx, obj-

obj-

goto bad;

}

/* Set the proto, parent, and class properties. */

newslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);

newslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);

newslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);

/* Clear above JSSLOT_CLASS so the GC doesn't load uninitialized memory. */

for (i = JSSLOT_CLASS + 1; i > nslots; i++)

newslots[i] = JSVAL_VOID;

/* Store newslots after initializing all of 'em, just in case. */

obj-

再看newObject中剩余的代码,真是容易多了,既然创建了map来存放属性名了,那么我们就要对应属性名来存放存放初始的属性值了。我们可以看到,每个创建的GC对象,都会被预先设置3个内置的属性,protoparentclass。然后,对剩余的slot,会设置undefinedJSVal_VOID会被解释成Undefined)。

到现在,我们的Global内置对象就已经初步创建完成了。



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1503245



http://www.niftyadmin.cn/n/3661255.html

相关文章

arcgis分隔图层重复出文件_ArcGIS实用制图技巧 | 处理好这些细节才能让图更专业...

地理信息系统(Geographic Information System或 Geo-Information system,GIS)有时又称为“地学信息系统”。它是一种特定的十分重要的空间信息系统。它是在计算机硬、软件系统支持下,对整个或部分地球表层(包括大气层)空间中的有关地理分布数…

postman是做什么的_Postman +Newman+Jenkins+钉钉实现持续集成的接口自动化

一、为什么选用postman工具做接口自动化测试postman调试工具无论对于开发和测试小白,还是技术大牛来说应该都耳熟能详,在过去的几年里大家对这款工具应用最广的用途是把当作接口调试的测试工具,它能发送几乎所有类型的HTTP请求,操…

基于DSL的组织机构模型 之一:预告

2007年05月31日 21:07:00 最近我对组织机构领域模型的ruby实现很是着迷。本来,已经知道今天下午要考IBM SOA Test 665,可是我昨天下午就已经开始开小差了,昨天晚上更是在几张白纸上写写画画的,搞到凌晨2点才算完,早晨起…

浏览器打印不居中_页面布局——绘图区域、文档类型和打印

2.1 绘图区域(The Drawing Area)文档窗口的大小可能与页面的绘图区域不同。文档窗口只能显示页面绘图区域的一部分。可以使用以下选项来设置绘图区域在屏幕上的显示:⑴Document Settings和 Page Setup可以设置页面大小和方向、页边距、页眉、…

arial字体可以商用吗_别人的PPT那些好看的字体哪里找的?免费可商用,都给你准备好了...

今天和大家说说在制作PPT时,应该如何快速替换字体,别人那些漂亮的字体,又是在哪里找到的?马上为大家揭晓!一、怎么快速更换PPT字体?1、自定义字体平时经常需要用到PPT制作的朋友,就可以自己预设…

放弃完美的需求管理

2007年05月24日 22:41:00 我当然晓得需求管理是怎么回事,我当然知道需求管理要做什么,我当然知道Telelogic的Doors比IBM的requisitepro的功能要强大,我当然知道在IBM和Telelogic的pk中,cc/cq的扩展功能要synergy/CM 和synergy / c…

python语言的内置对象类型_Python内置对象类型

核心数字类型:数字:int,long,float,complex,bool字符:str,unicode列表:list字典:dict元组:tuple文件:file其他类型:集合(s…

施密特正交化计算器_线性代数20——格拉姆-施密特正交化

标准正交向量有一堆向量, ,它们两两正交,这意味着这些向量满足:一个向量没法和自己正交,在i j时,让 ,这相当于 模长等于1:向量的转置乘以自身等于1,意味着这个向量是单位…