论坛首页 综合技术论坛

(新增官方回复)对【无类语言的OOP(JavaScript描述) 】一贴中第一个代码段的不同意见

浏览 26041 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-07-17  
本来吗,想让 keshin 本人把他上面那个回帖该一下的,后来看他人 offline 了,就算了。

说实在的,看到上面那张帖子,我产生了一种想哭的感觉,因为我已经非常细心地解释了每一个细节,但竟然因为少引用了一下 keshin 的代码,然后,转折用语又写得又太小,
引用
解决下一个问题,你曾经写过的返回 false 的代码:

结果 keshin 看错了,以为我一直在说下面我引用的那段代码,得出结论,我先说函数可 join,後说不可,然后我就崩溃了。
其实是这样的,前面我默认引用了你上一帖返回 true 的代码,讲了一大堆,说这里的函数对象可以被 join;后来话头一转,又引用一段返回 false 的代码,说这里的函数对象不可被 join——不知道现在你明白了没有。

然后(这个问题还是怪我太懒),只说了一句
引用
第 13.1.1 节,Equated Grammar Productions 中的内容已经讲过,没看见拉倒。

就不说了。其实,这里我想说的是,关于函数相等性测试的优化作用不说了。如果谈到 true, false 我是不可能谈实现问题的。

最后一个问题,我自我检讨一下,作出
引用
对于任意两个函数,规范指出,函数比较必须返回 false

这样的回答,是十分不负责任的,因为可以混淆的地方太多了。不行的话,你们去看我上一帖吧,那里说的还可以。

然后再回顾一下我说的意思:函数在实现中(应该)只有一个;作为程序中的一员出现时,是以对象形式出现的,比较比的是对象,这是根据是否能被 join 判断的。函数相等与 === 不是同一级别的问题。另外,整个讨论跟你引用的那段红字一点关系也没有。

至于你最后说的 ECMA 的回复,他们说的很客观,意思是优化未必启动。我想了一下,觉得这可能和数据流分析的结果有关,而数据流分析会受运行时情况影响,而且是个概率算法,优化是否启动因此不确定。这是我的猜测,可能错得很彻底,因为我也不可能对 Rhino 研究很透;而且如果谈到这些,那就和你的初衷背离了不止一点了,刨根问底也要有个度嘛。

哦对了,刚才又看到回了一个帖子。注意一下,它说的是另一种优化,认为此时可能可以 join 两个被产生函数,这个超纲了。
哟,这才看到,
引用
至于说相等性测试对于函数是无意义的...

不知道这句你是打哪儿找来的,为什么还放在最后一句,搞的我很没面子啊。还是那句话,以我前一帖为准吧。

最后说一下,这个帖子我不想再回了,如果还不明所以的话,私下交流一下也就算了,这种事情不登大雅之堂。
0 请登录后投票
   发表时间:2007-07-17  
之所以会有这个贴,不过是因为同事给我的一个链接……对于这个问题我也没兴趣再继续下去。说点感想就结了吧。
确实,我不懂什么编译原理,所谓的规范也不过这两天补的,不过我想所有的代码,所有的机器语言都是逻辑的,或者说,一个结果必然有他的因,如果无法对一个现象做出合理的解释或者根本不去解释,我只能选择怀疑。
也许在以后的什么时候再看到这个帖子,我会发现我错了,至于现在,我的观点就在我的所有帖子里,也懒得去整理了。
洗洗睡吧。
打搅各位了,祝观者晚安
0 请登录后投票
   发表时间:2007-07-18  
牛人把javascript都研究到这种地步了!
说的都看不懂。以后要好好学习学习javascript了。
0 请登录后投票
   发表时间:2007-07-18  
keshin 写道
之所以会有这个贴,不过是因为同事给我的一个链接……对于这个问题我也没兴趣再继续下去。说点感想就结了吧。
确实,我不懂什么编译原理,所谓的规范也不过这两天补的,不过我想所有的代码,所有的机器语言都是逻辑的,或者说,一个结果必然有他的因,如果无法对一个现象做出合理的解释或者根本不去解释,我只能选择怀疑。
也许在以后的什么时候再看到这个帖子,我会发现我错了,至于现在,我的观点就在我的所有帖子里,也懒得去整理了。
洗洗睡吧。
打搅各位了,祝观者晚安


较真的态度很值的尊敬,聊表敬意,道理是越辩越明,我觉的这帖子良好不过分。
0 请登录后投票
   发表时间:2007-07-18  
2位这样的讨论,我想对谁都是有好处的,对于我们这些只看没有说话的人,也有很大的启发,希望这样的气氛能继续下去
0 请登录后投票
   发表时间:2007-07-18  

帖子结束了,但我和Lich_Ray的私下讨论却并没有完全结束,征得Lich_Ray的同意后,我将我们私下讨论的结论贴出来。也算给这次讨论画个句号:

Lich_Ray 写道
keshin 写道
不好意思,又发一条,我刚才调用一个引用某函数的变量的构造器属性时,发现确实是一个内建的Function对象,因此貌似相等性测试来证明function的内存地址确实不合理,那么我的观点改为,也许function本身确实只有一个(之所以也许,因为确实我要学的还太多),但Function对象却可能有多个,这同样是一个浪费。讨论暂时到此为止吧,很高兴能有这样一场讨论。

感谢上帝!你这次的回信总算是知道我在说什么了...
引用
也许function本身确实只有一个(之所以也许,因为确实我要学的还太多),但Function对象却可能有多个,这同样是一个浪费。

就是这个意思,形而上地看是精确的。
很高兴看到JavaEye上又多一个肯用功的程序员。

不过有一点要提醒一下,对于JavaScript语义来说,没有"function 本身"这个东西,这只是实现角度的理解。

PS: 你曾经引用的一段其中有代码的 ECMA-262 片段
虽然与这个问题无关,但给了我一个有关语言形式语义学方面的启发,这段文字

引用
an implementation is allowed, but not required, to join b1 and b2. In fact, it may make b1 and b2 the same object because there is no way to detect the difference between their [[Scope]] properties.


出现的原因和等式推理的失效有关,有时间我得研究一下

尘埃算是落定,很高兴能有这样一次讨论,不仅仅因为是我对这部分的知识有了更深层次的理解,更因为此事提醒了我交流很重要,交流的方式同样重要。

感谢同事LQ给我的那个链接,那是一切的开端。

0 请登录后投票
   发表时间:2007-07-19  
楼主蛮有钻研精神的,还给ecma写信,而且ecma的人还蛮耐心的回答了,呵呵。不过两位的讨论中都有一些错误,俺有空来说一下。

0 请登录后投票
   发表时间:2007-07-19  
Lich_Ray 写道
首先,根据我列出的 ECMAScript 规范,识别“相等”函数需要进行函数代码的字符串比较。


不知道你是怎么得出“需要字符串比较”这样荒谬的结论的。规范说的是:Both uses obtained their FunctionBody from the same location in the source text of the same
ECMAScript program.

说白了,就是必须是从同一个函数体产生出来的。这里哪里需要字符串比较呢?由此,你后面的解说也属无效。

Lich_Ray 写道

还有,让prototype的版本的构造函数中有一次引用赋值,否则就成了只创建对象而没有构造函数执行的版本了。


就我所知的目前所有主流的js引擎,优化力度都是相当小的,不存在把空函数调用取消这样的优化。

Lich_Ray 写道
现在来解释你所说的函数比较返回 false 什么的问题。这根本就不是问题。对于任意两个函数,规范指出,函数比较必须返回 false;在进行引用赋值时,首先把函数封装为对象,引用比较执行函数对象的比较,返回 true。我所说的函数的相等性测试,指的是 JavaScript 实现中的一种机制(所有 ECMAScript 规范中表明“build-in”的章节都属此类),与语言的外在表现无关;在这里就是相等性测试与 === 测试无关,因为二者根本就不是同一概念。一个语言实现的优化,目的就是要在你从外部看不出来的情况下提高性能;现在看到的宏观表现,必然是语言语义层所反映的内容而非未优化的后果。


你说的是没错。但是你的表达不严谨。既然不 ===,就不能说是“相等性”。再有一点,规范所说的几个优化步骤实际上所有的引擎都不是按照规范做的。如果按照规范的话,等价function会被joined起来,并且===比较会是true。实际上就这点而言,我认为规范本身是有问题的。
0 请登录后投票
   发表时间:2007-07-20  
前面的代码比后面的快是肯定的。但是差那么多,完全不是因为你想象中的原因。

而是因为你是在IE6中测试的。你可以换用FF,Opera,Safari或者IE7来测试。

IE6(准确的说,是jscript 5.7之前的版本)存在一个重要的bug,就是创建对象的速度随对象数量呈指数下降。

keshin 写道:

那我们按3楼的说法来做个测试:

js 代码
 
  1. function Darkness() {   
  2. }   
  3.   
  4. Darkness.prototype.turnOn = function () {   
  5.   alert("bingo");   
  6. }   
  7. time = {}    
  8. var b = [];   
  9. time.org = new Date().toTimeString()      
  10. for (var i = 0; i < 100000; i++) {      
  11.     b[i] = new Darkness();      
  12. }      
  13. time.after = new Date().toTimeString()      
  14. alert(time.org+'\n'+time.after)      
  15.   
  16. function Light() {   
  17.   this.turnOn = function () {   
  18.     alert("bingo");   
  19.   }   
  20. }   
  21. var a = []     
  22. time.org = new Date().toTimeString()      
  23. for (var i = 0; i < 100000; i++) {      
  24.     a[i] = new Light();      
  25. }      
  26. time.after = new Date().toTimeString()      
  27. alert(time.org+'\n'+time.after)     

结果很遗憾,前面那个花了5秒钟左右,而后面这个花了我一分半钟。

能给我解释一下么?




0 请登录后投票
   发表时间:2007-07-20  
如果你不是把所有创建的对象都放入数组。而是仅仅 new XXX(); 则这些对象一被创建出来就可被垃圾回收。这样测试的结果相差是很少的。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics