`
sunshineormer
  • 浏览: 12394 次
  • 来自: ...
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

[领域]Javascript Hacking Guide 系列文章 (2007-2-7更新到part6)

阅读更多

那天听东东将javascript,他讲得也匆忙,我听得也犯晕,心想如果能够建立起javascript的内存对象模型该多好啊。可是在网上找了好久,也没有发现javascript的Hacking guide,不经意间,却找到了ruby hacking guide,不错不错。还好有mozilla 中蜘蛛猴的源代码,我想离真正建立javascript的对象模型(内存模型)已经不远了。

仿照ruby hacking guide的做法,先把已经掌握的资料用图表示出来,关于其之间的详细的关系,我会在后面的文章中举例说明。

 

图示说明:椭圆边框的部分是c的结构体(struct),带圆点的线条代表指针,在椭圆外的是该结构体所在的文件。

这算javascript内存模型的第一部分吧。老是等研究完了再写,恐怕就没有激情了。呵呵

 
分享到:
评论
10 楼 sunshineormer 2007-02-07  
 
<p class='MsoNormal'><span style=''>书接上回,我们说到</span><span lang='EN-US'>global</span><span style=''>对象的初始创建已经完成了。那,你肯定会问了,为什么说是初始创建,而不是完整的创建呢?要回答这个问题,还要从</span><span lang='EN-US'>ECMA262</span><span style=''>说起:</span></p>
<p class='MsoNormal'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal'><span style=''>在</span><span lang='EN-US'>ECMA262</span><span style=''>,强调了</span><span lang='EN-US'>Global</span><span style=''>这个全局函数的很多信息,比如说,这个内置对象是先于</span><span lang='EN-US'>Context</span><span style=''>就存在了的。比方说,在默认的情况下,我们调用的方法,其实都是</span><span lang='EN-US'>Global</span><span style=''>这个对象的方法。比方说</span> <span style=''>:</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>var obj = new Object();</span></p>
</div>
<p class='MsoNormal'><span style=''>其实也就等于</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>var obj = new this.Object();</span></p>
</div>
<p class='MsoNormal'><span style=''>像</span><span lang='EN-US'>parseInt</span><span style=''>这样的方法,其实也都是挂在</span><span lang='EN-US'>Global</span><span style=''>名下的。</span><span lang='EN-US'>Global</span><span style=''>对象下,有若干属性,包括</span><span lang='EN-US'>Object,Array,Boolean,String…. </span><span style=''>这么说你肯定就明白了。其他的内置对象,都是</span><span lang='EN-US'>Global</span><span style=''>的一个属性值。其实,不光内置对象,所有的新定义的</span><span lang='EN-US'>function </span><span style=''>,也都会在定义后(即通过</span><span lang='EN-US'>function</span><span style=''>关键字)在</span><span lang='EN-US'>Global</span><span style=''>的属性列表中增加一个指向自己的属性。</span></p>
<p class='MsoNormal'><span style=''>那么,我们可以想一下,</span><span lang='EN-US'>Global</span><span style=''>和</span><span lang='EN-US'>Object</span><span style=''>之间的关系,真的是很微妙啊。</span><span lang='EN-US'>Global.prototype</span><span style=''>和</span><span lang='EN-US'>Object.prototype</span><span style=''>会是什么样的关系呢?</span></p>
<p class='MsoNormal'><span style=''>如果你是一个心急的人,一点会说:“写一段代码不就知道了吗?”。你的程序是不是这样写的?</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>document.writeln(global.prototype = = …</span></p>
</div>
<p class='MsoNormal'><span lang='EN-US'>sorry,</span><span style=''>忘了告诉你了,</span><span lang='EN-US'>global</span><span style=''>对象是不能这么访问的。你在程序中写:</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>document.writeln(global);</span></p>
</div>
<p class='MsoNormal'><span style=''>将会打出</span><span lang='EN-US'>undefined.</span><span style=''>不过,这个</span><span lang='EN-US'>Global</span><span style=''>对象又缺省存在,我们应该怎么去访问它呢?请让我先卖一个关子吧。</span></p>
<p class='MsoNormal'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal'><span style=''>有了</span><span lang='EN-US'>Global</span><span style=''>的这个概念以后,我们继续来分析源代码。从</span><span lang='EN-US'>part4</span><span style=''>-</span><span lang='EN-US'>part5</span><span style=''>,我们基本上只在围绕着一个函数做文章,</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>glob = JS_NewObject(cx, &amp;global_class, NULL, NULL);</span></p>
</div>
<p class='MsoNormal'><span style=''>这个函数的调用关系讲完之后,我们就要看下面的代码段了。</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>JS_InitStandardClasses(cx, glob)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>JS_DefineFunctions(cx, glob, shell_functions)</span></p>
</div>
<p class='MsoNormal'><span style=''>从名字上看,我们是要在</span><span lang='EN-US'>glob</span><span style=''>这个对象下,创建并挂接系统内置的对象了(事实也果真如此)。</span></p>
<p class='MsoNormal'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal'><span lang='EN-US'>JS_InitStandardClasses</span><span style=''>这个函数定义在</span><span lang='EN-US'>jsapi.c </span><span style=''>这个文件中,我们可以很容易的找到其中的重要部分:</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>/* Define a top-level property 'undefined' with the undefined value. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>atom = cx-&gt;runtime-&gt;atomState.typeAtoms[JSTYPE_VOID];</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!<span style='color: red;'>OBJ_DEFINE_PROPERTY</span>(cx, obj, ATOM_TO_JSID(atom), <span style='color: red;'>JSVAL_VOID</span>,</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>                             </span>NULL, NULL, JSPROP_PERMANENT, NULL)) {</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>return JS_FALSE;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>}</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>/* Function and Object require cooperative bootstrapping magic. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!<span style='color: red;'>js_InitFunctionAndObjectClasses(cx, obj)</span>)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>return JS_FALSE;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>/* Initialize the rest of the standard objects and functions. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>return<span style='color: red;'> js_InitArrayClass(cx, obj) &amp;&amp;&lt;o:p&gt;&lt;/o:p&gt;</span></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US' style='color: red;'><span style=''>           </span>js_InitBlockClass(cx, obj) &amp;&amp;&lt;o:p&gt;&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>           </span>js_InitBooleanClass(cx, obj) &amp;&amp;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>           </span>js_InitCallClass(cx, obj) &amp;&amp;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>           </span>js_InitExceptionClasses(cx, obj) &amp;&amp;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>           </span>js_InitMathClass(cx, obj) &amp;&amp;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>                     </span></span><span style=''>。。。。</span></p>
</div>
<p class='MsoNormal'><span style=''>我在这段代码中,找到的几个处比较重要的函数调用,用红颜色圈了出来。</span></p>
<p class='MsoNormal'><span style=''>第一个部分是一个宏:</span><span lang='EN-US' style='color: red;'>OBJ_DEFINE_PROPERTY</span><span style=''>,</span><span style=''>这个宏的主要作用是调用函数指针,来给</span><span lang='EN-US'>glob</span><span style=''>对象创建一个新的属性,属性的类型是</span><span lang='EN-US'>JSVAL_VOID,</span><span style=''>这说明,</span><span lang='EN-US'>ECMA262</span><span style=''>中要求的,</span><span lang='EN-US'>Undefined</span><span style=''>属性是</span><span lang='EN-US'>Global</span><span style=''>的一个属性,已经得到了实现。</span></p>
<p class='MsoNormal'><span style=''>第二部分,是我们的主角,弄懂了这个函数,基本上就可以初步理解</span><span lang='EN-US'>ECMAScript</span><span style=''>的对象模型了。而且,它的注释也很有意思,使用了</span><span lang='EN-US'>cooperative bootstrapping magic</span><span style=''>这样的字眼。好的,那就让我们跑到后台去,看看魔术师的鬼把戏是怎么出来的吧。</span></p>
<p class='MsoNormal'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal'><span lang='EN-US'>js_InitFunctionAndObjectClasses</span><span style=''>仍然在同文件中,所以不用调转就可以找到。</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>/* If cx has no global object, use obj so prototypes can be found. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!cx-&gt;globalObject)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>JS_SetGlobalObject(cx, obj);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>/* Record Function and Object in cx-&gt;resolvingTable, if we are resolving. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span style=''>。。。。</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>/* Initialize the function class first so constructors can be made. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>fun_proto =<span style='color: red;'> js_InitFunctionClass(cx, obj);</span></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!fun_proto)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>goto out;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>/* Initialize the object class next so Object.prototype works. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>obj_proto = js_InitObjectClass(cx, obj);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!obj_proto) {</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>fun_proto = NULL;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>goto out;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>}</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>/* Function.prototype and the global object delegate to Object.prototype. */</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>OBJ_SET_PROTO(cx, fun_proto, obj_proto);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!OBJ_GET_PROTO(cx, obj))</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>OBJ_SET_PROTO(cx, obj, obj_proto);</span></p>
</div>
<p class='MsoNormal'><span style=''>这个程序的开头两大段,做的工作,我猜想我们可以跳过,不知道正不正确,我更想从</span><span lang='EN-US'>js_InitFunctionClass(cx, obj)</span><span style=''>开始(标红的部分)。我们可以看到,我们还是把</span><span lang='EN-US'>global</span><span style=''>当成参数传到了这个函数体中,这样,我们得到的的返回值,就是</span><span lang='EN-US'>Function.prototype;</span><span style=''>同样,如果我们继续向下看,就会看到</span><span lang='EN-US'>js_InitObjectClass(cx, obj)</span><span style=''>这个函数,从返回值、注释加上对函数名的推测,我们会看到,函数运行后返回了</span><span lang='EN-US'>Object.prototype</span><span style=''>。</span></p>
<p class='MsoNormal'><span style=''>然后呢,我们留意一下注释,哦,我的老天啊。我的猜测是没有错的</span><span lang='EN-US'>Function.prototype</span><span style=''>和</span><span lang='EN-US'>Global</span><span style=''>对象的</span><span lang='EN-US'>prototype</span><span style=''>被委托给了</span><span lang='EN-US'>Object.prototype.</span><span style=''>这还不够让我们兴奋的吗?</span></p>
<p class='MsoNormal'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal'><span style=''>允许兴奋,可不要兴奋大发劲了啊。我们还有正事没有做呢。</span><span lang='EN-US'>js_InitFunctionClass</span><span style=''>还在等着我们去解密呢。</span></p>
<p class='MsoNormal'><span style=''>这个函数在</span><span lang='EN-US'>jsfun.c</span><span style=''>中有定义,麻烦你动手先将它找出来。</span></p>
<p class='MsoNormal'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>JSObject *</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>js_InitFunctionClass(JSContext *cx, JSObject *obj)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>{</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>JSObject *proto;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>JSAtom *atom;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>JSFunction *fun;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>proto = JS_InitClass(cx, obj, NULL, &amp;js_FunctionClass, Function, 1,</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>                </span><span style=''>         </span>function_props, function_methods, NULL, NULL);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!proto)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>return NULL;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>atom = js_Atomize(cx, js_FunctionClass.name, strlen(js_FunctionClass.name),</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>                      </span>0);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!atom)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>goto bad;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, NULL);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!fun)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>goto bad;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>fun-&gt;u.i.script = js_NewScript(cx, 1, 0, 0);</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>if (!fun-&gt;u.i.script)</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>        </span>goto bad;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>fun-&gt;u.i.script-&gt;code[0] = JSOP_STOP;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>    </span>fun-&gt;flags |= JSFUN_INTERPRETED;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; text-indent: 21pt; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>return proto;</span></p>
</div>
<p class='MsoNormal' style='text-indent: 21.75pt;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='text-indent: 21.75pt;'><span style=''>为了简单起见,我将这个函数的调用图先列出来:</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>js_InitFunctionClass</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>       </span>JS_InitClass</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>              </span>js_Atomize</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>              </span>js_NewObject</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>                     </span>js_NewGCThing</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>       </span>js_Atomize</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>       </span>js_NewFunction</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><span style=''>              </span>js_NewGCThing</span></p>
</div>
<p class='MsoNormal' style='text-indent: 21.75pt;'><span lang='EN-US'>&lt;o:p&gt; &lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='text-indent: 21.75pt;'><span style=''>那么,我们可以从这个调用图中推导出什么来呢?咱们下回书接着说。</span></p>
9 楼 sp42 2007-02-06  
系统地建立JS知识和对其原理的理解 ,这是一个图文并茂的好材料
8 楼 sunshineormer 2007-02-06  
typeof Function == function。(图中灰的表示typeof的返回值是function)
7 楼 jianfeng008cn 2007-02-06  
typeof function ==object?

很好的文章,让不懂c系列的我感觉很有收获,回头再好好学学c系列的语言。
6 楼 sunshineormer 2007-02-06  
预告内容: 在接下来的文章中,将对global全局对象进行详细讲解,并给大家分析创建函数的过程。根据这部分内容,将对前面的图片进行部分的修改。
5 楼 sunshineormer 2007-02-06  
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><font>part5:</font></span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><font>map</font></span><span style=''>是</span><span lang='EN-US'><font>JSObject</font></span><span style=''>的一个重要属性,存放一个对象的所有的属性的入口。要想了解</span><span lang='EN-US'><font>map</font></span><span style=''>,就需要打开</span><span lang='EN-US'><font>jsobj.h</font></span><span style=''>文件,看里面的定义。</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>struct JSObject {</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSObjectMap *map;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>jsval<span style=''>       </span>*slots;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>};</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>很自然的,我们还要找到</span><span lang='EN-US'><font>JSObjectMap</font></span><span style=''>的定义,它也在</span><span lang='EN-US'><font>jsobj.h</font></span><span style=''>文件中</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>struct JSObjectMap {</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>jsrefcount<span style=''>  </span>nrefs;<span style=''>          </span>/* count of all referencing objects */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSObjectOps *ops;<span style=''>           </span>/* high level <span style='color: red;'>object operation vtable</span> */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>uint32<span style=''>      </span>nslots;<span style=''>         </span>/* length of obj-&gt;slots <span style='color: red;'>vector</span> */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>uint32<span style=''>      </span>freeslot;<span style=''>       </span>/* index of next free obj-&gt;slots element */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>};</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>在这个定义中,最重要的信息隐含在注释中,第一个是对</span><span lang='EN-US'><font>ops</font></span><span style=''>的注释,我们会看到</span><span lang='EN-US'><font>ops</font></span><span style=''>其实是一个</span><span lang='EN-US'><font>virtual table</font></span><span style=''>。这表示,对象的所有的属性名,都存放在这个</span><span lang='EN-US'><font>vtable</font></span><span style=''>中;第</span><span lang='EN-US'><font>2</font></span><span style=''>个信息是对</span><span lang='EN-US'><font>nslots</font></span><span style=''>的注释,它提及</span><span lang='EN-US'><font>obj-&gt;slots</font></span><span style=''>其实是一个</span><span lang='EN-US'><font>vector</font></span><span style=''>。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>这如同在告诉我们,我们在定义一个对象的属性时,属性的名称和类型等信息,会通过</span><span lang='EN-US'><font>ops</font></span><span style=''>增加到属性表中,属性的值会对应放到</span><span lang='EN-US'><font>slots</font></span><span style=''>这个</span><span lang='EN-US'><font>vector</font></span><span style=''>中。例如:</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>var obj = new Object();</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>obj.a = 5;</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><span style=''><font> </font></span></span><span style=''>那么“</span><span lang='EN-US'><font>a</font></span><span style=''>”这个属性的类型是整型的,</span><span lang='EN-US'><font>slots</font></span><span style=''>中增加了个新的值</span><span lang='EN-US'><font>5</font></span><span style=''>。仔细看去,</span><span lang='EN-US'><font>ops</font></span><span style=''>是</span><span lang='EN-US'><font>JSObjectOps</font></span><span style=''>这个结构体中,我们可以在</span><span lang='EN-US'><font>jsapi.h</font></span><span style=''>中找到这个结构体的定义:</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>struct JSObjectOps {</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>/* Mandatory non-null function pointer members. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSNewObjectMapOp<span style=''>    </span><span style='color: red;'>newObjectMap;</span></font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSObjectMapOp<span style=''>       </span>destroyObjectMap;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSLookupPropOp<span style=''>      </span>lookupProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSDefinePropOp<span style=''>      </span><span style='color: red;'>defineProperty;</span></font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyIdOp<span style=''>      </span><span style='color: red;'>getProperty;&lt;o:p&gt;&lt;/o:p&gt;</span></font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyIdOp<span style=''>      </span>setProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSAttributesOp<span style=''>      </span>getAttributes;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSAttributesOp<span style=''>      </span>setAttributes;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyIdOp<span style=''>      </span>deleteProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSConvertOp<span style=''>         </span>defaultValue;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>  </span><span style=''>  </span>JSNewEnumerateOp<span style=''>    </span>enumerate;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSCheckAccessIdOp<span style=''>   </span>checkAccess;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>/* Optionally non-null members start here. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSObjectOp<span style=''>          </span>thisObject;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyRefOp<span style=''>     </span>dropProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSNative<span style=''>            </span>call;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSNative<span style=''>            </span>construct;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSXDRObjectOp<span style=''>       </span>xdrObject;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSHasInstanceOp<span style=''>     </span>hasInstance;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSSetObjectSlotOp<span style=''>   </span>setProto;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSSetObjectSlotOp<span style=''>   </span>setParent;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSMarkOp<span style=''>            </span>mark;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSFinalizeOp<span style=''>        </span>clear;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSGetRequiredSlotOp getRequiredSlot;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSSetRequiredSlotOp setRequiredSlot;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>};</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>我们可以简单的浏览一下其中的函数指针名称,创建</span><span lang='EN-US'><font>object</font></span><span style=''>的</span><span lang='EN-US'><font>map</font></span><span style=''>,定义属性,删除属性,给属性设置值或者获取属性值。。。。闭上眼睛想一想,这其中的函数指针是如此之多,所以一个对象的属性的类型判断(比如是整型还是</span><span lang='EN-US'><font>String</font></span><span style=''>还是其他的)或者是属性名或者属性值的存放,都是通过预先定义好的指针函数来完成。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span style=''><font size='3'>我们甚至可以用一个新的示意图来表示这一切:</font></span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> <img src='http://sunshineormer.blogdriver.com/sunshineormer/inc/ECMAScript5.jpg' alt=''/></font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'><font size='3'><font>&lt;v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;/v:stroke&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;/v:f&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;/v:f&gt;&lt;v:f eqn="sum @10 21600 0"&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"&gt;&lt;/v:path&gt;&lt;o:lock aspectratio="t" v:ext="edit"&gt;&lt;/o:lock&gt;&lt;/v:shapetype&gt;&lt;v:shape id="_x0000_i1025" style="WIDTH: 213.75pt; HEIGHT: 131.25pt" type="#_x0000_t75"&gt;&lt;v:imagedata o:title="" src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_image001.png"&gt;&lt;/v:imagedata&gt;&lt;/v:shape&gt;</font></font></span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>我们可以这样去想,有一个</span><span lang='EN-US'><font>table</font></span><span style=''>,里面存放对象的属性列表。根据</span><span lang='EN-US'><font>ruby hacking guide</font></span><span style=''>的说法,我们可以想像,有一张大的表,存放所有的对象的属性,也可能每个对象有自己的属性表。但,这属于具体实现的范畴,我们只要明白每个对象有属于自己的属性表,对表格中的行或者列进行操作时,是由</span><span lang='EN-US'><font>JSObjectOps</font></span><span style=''>这个结构体中的指针函数来完成的就可以了。</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>/*</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* Share proto's map only if it has the same JSObjectOps, and only if</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* proto's class has the same private and reserved slots as obj's map</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* and class have.<span style=''>  </span>We assume that if prototype and object are of the</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* same class, they always have the same number of computed reserved</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* slots (returned via clasp-&gt;reserveSlots); otherwise, prototype and</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* object classes must have the same (null or not) reserveSlots hook.</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>*/</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>if (proto &amp;&amp;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>(map = proto-&gt;map)-&gt;ops == ops &amp;&amp;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>((protoclasp = OBJ_GET_CLASS(cx, proto)) == clasp ||</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>         </span>(!((protoclasp-&gt;flags ^ clasp-&gt;flags) &amp;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>(JSCLASS_HAS_PRIVATE |</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>             </span>(JSCLASS_RESERVED_SLOTS_MASK &lt;&lt; JSCLASS_RESERVED_SLOTS_SHIFT))) &amp;&amp;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>          </span>protoclasp-&gt;reserveSlots == clasp-&gt;reserveSlots)))</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>{</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>/*</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>         </span>* Default parent to the parent of the prototype, which was set from</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>         </span>* the parent of the prototype's constructor.</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>         </span>*/</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>if (!parent)</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>parent = OBJ_GET_PARENT(cx, proto);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>/* Share the given prototype's map. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>obj-&gt;map = js_HoldObjectMap(cx, map);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>/* Ensure that obj starts with the minimum slots for clasp. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>nslots = JS_INITIAL_NSLOTS;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>} else {</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>/* Leave parent alone.<span style=''>  </span>Allocate a new map for obj. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>map = ops-&gt;newObjectMap(cx, 1, ops, clasp, obj);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>if (!map)</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>goto bad;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>obj-&gt;map = map;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>/* Let ops-&gt;newObjectMap set nslots so as to reserve slots. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>nslots = map-&gt;nslots;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>}</font></font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><font>Ok</font></span><span style=''>,我们在上回书说到有若干的判断条件,就是为了创建一个</span><span lang='EN-US'><font>map</font></span><span style=''>,并设置为</span><span lang='EN-US'><font>obj-&gt;map</font></span><span style=''>的属性――不管是用</span><span lang='EN-US'><font>parent</font></span><span style=''>的原型来创建,还是单独创建新的</span><span lang='EN-US'><font>map</font></span><span style=''>(</span><span lang='EN-US'><font>if </font></span><span style=''>。。。</span><span lang='EN-US'><font>else </font></span><span style=''>部分),最终都是为了这个目的。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>/* Allocate a slots vector, with a -1'st element telling its length. */</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>newslots = AllocSlots(cx, NULL, nslots);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>if (!newslots) {</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>js_DropObjectMap(cx, obj-&gt;map, obj);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>obj-&gt;map = NULL;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>goto bad;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>}</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>/* Set the proto, parent, and class properties. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>newslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>newslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>newslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>/* Clear above JSSLOT_CLASS so the GC doesn't load uninitialized memory. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>for (i = JSSLOT_CLASS + 1; i &lt; nslots; i++)</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>newslots[i] = JSVAL_VOID;</font></font></span></p>
<p class='MsoNormal' style=''/></div>
4 楼 sunshineormer 2007-02-06  
<p>part4 :</p>
<p>在正式开始之前,先说点关于RHG的话题,我的JHG系列,基本是在仿照着RHG的风格在写作。RHG的述事风格很有条理性,并且会指导你跳过跳过再跳过一些无关痛痒的程序片段。这是对的,在一大堆程序中,能够快速准确的定位,不是件很容易的事情。</p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span style=''><font size='3'>从今天开始,我将讲述我对蜘蛛猴源代码的查找过程:</font></span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><font>在js.c </font></span><span style=''>找到</span><span lang='EN-US'><font>main</font></span><span style=''>里面的调用过程,注意,下面的函数都是精简过的,而且是平级的关系:</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>rt = JS_NewRuntime(...</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>cx = JS_NewContext(rt,...</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>glob = JS_NewObject(cx, &amp;global_class, NULL, NULL);</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>JS_InitStandardClasses(cx, glob)</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>JS_DefineFunctions(cx, glob, shell_functions)</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><font>ok,</font></span><span style=''>现在来看一下,运行时和上下文环境是解释引擎的初始化,可以先跳过,哈,我们真正关心的肯定是从</span><span lang='EN-US'><font>glob</font></span><span style=''>开始的那</span><span lang='EN-US'><font>3</font></span><span style=''>句了:</span><span lang='EN-US'><font>glob</font></span><span style=''>是</span><span lang='EN-US'><font>ECMA262</font></span><span style=''>中要求的内置全局对象,这里有我们比较感兴趣的</span><span lang='EN-US'><font>NewObject</font></span><span style=''>方法</span><span lang='EN-US'><font>;</font></span><span style=''>紧接其后的,将是对其他内置对象的创建过程(</span><span lang='EN-US'><font>JS_InitStandardClasses</font></span><span style=''>)</span><span lang='EN-US'><font>;</font></span><span style=''>最后,我们可以看看全局对象</span><span lang='EN-US'><font>global</font></span><span style=''>都有哪些方法。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span lang='EN-US'><font>JS_NewObject</font></span><span style=''>的函数声明,被定义在</span><span lang='EN-US'><font>jsobj.h</font></span><span style=''>中,函数定义在</span><span lang='EN-US'><font>jsobj.c</font></span><span style=''>中:</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span style=''><font size='3'>:</font></span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>extern JSObject *</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>记住,因为是要初始化</span><span lang='EN-US'><font>glob</font></span><span style=''>对象,我们在传递参数是,</span><span lang='EN-US'><font>proto</font></span><span style=''>和</span><span lang='EN-US'><font>parent</font></span><span style=''>都传递了</span><span lang='EN-US'><font>NULL</font></span><span style=''>。这样,有效传递到函数体中的,就只有刚刚创建的上下文环境(</span><span lang='EN-US'><font>cx</font></span><span style=''>)和</span><span lang='EN-US'><font>clasp</font></span><span style=''>了。</span><span lang='EN-US'><font>clasp</font></span><span style=''>的值被赋予了</span><span lang='EN-US'><font>global_class,</font></span><span style=''>这是个全局变量,定义在</span><span lang='EN-US'><font>js.c</font></span><span style=''>中</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>JSClass global_class = {</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>"global", JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JS_PropertyStub,<span style=''>  </span>JS_PropertyStub,</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JS_PropertyStub,<span style=''>  </span>JS_PropertyStub,</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>global_enumerate, (JSResolveOp) global_resolve,</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JS_ConvertStub,<span style=''>   </span>JS_FinalizeStub,</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSCLASS_NO_OPTIONAL_MEMBERS</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>};</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>在这个变量中,我们发现了“</span><span lang='EN-US'><font>global</font></span><span style=''>”这个单词,结合</span><span lang='EN-US'><font>JSClass</font></span><span style=''>这名字,再根据</span><span lang='EN-US'><font>MFC</font></span><span style=''>等框架的经验,很容易的我们就可以联想到,这是用来做动态生成和</span><span lang='EN-US'><font>RTTI</font></span><span style=''>的类名。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>要想看懂这个结构体,一点也不难,只需到</span><span lang='EN-US'><font>jsapi.h</font></span><span style=''>中找</span><span lang='EN-US'><font>JSClass</font></span><span style=''>的定义即可。里面也没有什么太多的玩意,只是有一堆的函数指针,我们只需简单留言其中的强制非空部分即可。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>struct JSClass {</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>const char<span style=''>          </span>*name;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>uint32<span style=''>              </span>flags;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>/* Mandatory non-null function pointer members. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyOp<span style=''>        </span>addProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyOp<span style=''>        </span>delProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyOp<span style=''>        </span>getProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSPropertyOp<span style=''>        </span>setProperty;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSEnumerateOp<span style=''>       </span>enumerate;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSResolveOp<span style=''>         </span>resolve;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSConvertOp<span style=''>         </span>convert;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSFinalizeOp<span style=''>        </span>finalize;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>/* Optionally non-null members start here. */</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSGetObjectOps<span style=''>      </span>getObjectOps;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSCheckAccessOp<span style=''>     </span>checkAccess;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSNative<span style=''>            </span>call;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSNative<span style=''>            </span>construct;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSXDRObjectOp<span style=''>       </span>xdrObject;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>  </span><span style=''>  </span>JSHasInstanceOp<span style=''>     </span>hasInstance;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSMarkOp<span style=''>            </span>mark;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>JSReserveSlotsOp<span style=''>    </span>reserveSlots;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>};</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>放眼望去,偶的老天,原来类的属性操作(增加属性,删除属性,查询和设置属性都是在这定义的啊)。要知道,在</span><span lang='EN-US'><font>javascript</font></span><span style=''>中,所有的</span><span lang='EN-US'><font>attributes</font></span><span style=''>和方法都是属性啊。按下不表。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>还是跳回到</span><span lang='EN-US'><font>newObject</font></span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>/* Bootstrap the ur-object, and make it the default prototype object. */</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>if (!proto) {</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>if (!js_GetClassId(cx, clasp, &amp;id))</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>return NULL;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>if (!js_GetClassPrototype(cx, parent, id, &amp;proto))</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>return NULL;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>if (!proto &amp;&amp;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>!js_GetClassPrototype(cx, parent, INT_TO_JSID(JSProto_Object),</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>                                  </span>&amp;proto)) {</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>            </span>return NULL;</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>}</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>}</font></font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span style=''><font size='3'>先看这段代码,简而言之,想做的事情是,找到要创建对象的原型,如果实在找不到,就使用缺省的原型对象。跳过。</font></span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span style=''><font size='3'>接下来的代码,</font></span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>/* Always call the class's getObjectOps hook if it has one. */</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>ops = clasp-&gt;getObjectOps</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>          </span>? clasp-&gt;getObjectOps(cx, clasp)</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>          </span>: &amp;js_ObjectOps;</font></font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>只是想找一个对象的操作方法集,因为我们在定义</span><span lang='EN-US'><font>global_class</font></span><span style=''>全局对象时,使用了</span><span lang='EN-US'><font>JSCLASS_NO_OPTIONAL_MEMBERS</font></span><span style=''>宏,可以很轻松的判定这个表达式如同:</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>ops = &amp;js_ObjectOps;</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span style=''><font size='3'>继续向后:</font></span></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>/*</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* Allocate a zeroed object from the <span style='color: red;'>GC heap</span>.<span style=''>  </span>Do this *after* any other</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* GC-thing allocations under js_GetClassPrototype or clasp-&gt;getObjectOps,</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>* to avoid displacing the newborn root for obj.</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>     </span>*/</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>    </span>if (!obj)</font></font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'><font><span style=''>        </span>return NULL;</font></font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>从注释中,我们可以轻松的看出,按照</span><span lang='EN-US'><font>ECMAScript</font></span><span style=''>的说法,对象被分配到</span><span lang='EN-US'><font>heap</font></span><span style=''>中,已经得到了实现了。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>被定义在了</span><span lang='EN-US'><font>jsgc.c</font></span><span style=''>中,我们不想太多的去看堆的</span><span lang='EN-US'><font>alloc</font></span><span style=''>分配,只要知道这里生成了一个空的</span><span lang='EN-US'><font>JSObject</font></span><span style=''>对象即可。</span></font></p>
<div style='padding-right: 4pt; padding-left: 4pt; background: silver; padding-bottom: 1pt; padding-top: 1pt;'>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>void *</font></span></p>
<p class='MsoNormal' style='border-right: medium none; padding-right: 0cm; border-top: medium none; padding-left: 0cm; background: silver; padding-bottom: 0cm; margin: 0cm 0cm 0pt; border-left: medium none; padding-top: 0cm; border-bottom: medium none;'><span lang='EN-US'><font size='3'>js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes)</font></span></p>
</div>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>再接着,是一大段的判断条件,想法很简单,既而是已经在</span><span lang='EN-US'><font>heap</font></span><span style=''>中创建了对象,就要给对象的</span><span lang='EN-US'><font>map</font></span><span style=''>和</span><span lang='EN-US'><font>slot</font></span><span style=''>进行赋值了:一种做法是判断了若干条件后,用原型的</span><span lang='EN-US'><font>map</font></span><span style=''>;另一种可能,是创建新的</span><span lang='EN-US'><font>map</font></span><span style=''>。</span></font></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><span lang='EN-US'>&lt;o:p&gt;<font size='3'> </font>&lt;/o:p&gt;</span></p>
<p class='MsoNormal' style='margin: 0cm 0cm 0pt;'><font size='3'><span style=''>你会问</span><span lang='EN-US'><font>map</font></span><span style=''>里面都存放了什么?呵呵。好问题。且听下回分解吧。</span></font></p>
<p> </p>
3 楼 sunshineormer 2007-02-06  
<p>part2:</p>
<p>感谢超德和梁健,你们是我前进的动力。</p>
<p><img src='http://sunshineormer.blogdriver.com/sunshineormer/inc/ECMAScript2.jpg' align='baseline' alt=' '/></p>
<p>昨天贴出来的,只能算是初步的编程模型,如果想弄清楚javascript的内存模型,必须看这幅图,不过这幅图还有一些简化的部分。以后会用程序来验证和说明这幅图的正确性,敬请期待。</p>
<p> part3:</p>
<p>跟东、雪和健讨论后,重新修改了图2,可以联系图1来思考它们之间的演进关系了。</p>
<p><img src='http://sunshineormer.blogdriver.com/sunshineormer/inc/ECMAScript3.jpg' align='baseline' alt=' '/></p>
<p>这个周末,基本上是跟指针,对象一起度过的。即使是在我偶而为之的睡梦中,也是在思考函数指针和指针函数。呵呵。</p>
<p>周日整理出来的继承(原型)链图,可以说是javascript对象基础中比较深的部分了。</p>
<p><img src='http://sunshineormer.blogdriver.com/sunshineormer/inc/ECMAScript4.jpg' align='baseline' alt=' '/></p>
<p>浅蓝色的,typeof() ==Object, 灰色的部分,typeof == Function。这里面只有FunctionPrototype出乎我的意料,我对它的期望值是浅蓝色,可是,运行程序的结果证明,它是灰色调的。</p>
<p> </p>
2 楼 sunshineormer 2007-02-06  
sorry,我写blog写惯了,喜欢一段一段的写。马上改正。
1 楼 ITeye管理员 2007-02-06  
请将这一系列的文章发在同一topic下,谢谢。

相关推荐

Global site tag (gtag.js) - Google Analytics