论坛首页 Web前端技术论坛

关于JavaScript的 貌似类(pseudo-classes)----不吐不快

浏览 4719 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-02  
----------------------原创翻译---------------------------
关于JavaScript的 貌似类(pseudo-classes)----不吐不快

作者:Zwetan Kjukov
原文出处:http://burrrned.zwetan.com/2005/08/raising-hell.html

关于David flanagan的人们怎么称呼JS的“貌似类(pseudo-classes)”的一博客(http://www.davidflanagan.com/blog/2005_07.html#000068),我有一大堆话要说,发表评论就不必了,我会在这里说。

ECMAScript里面是没有类的,这点在 ECMA-262 规范里说得非常清楚。

引用
4.2.1 Objects
ECMAScript does not contain proper classes such as those in
C++, Smalltalk, or Java, but rather, supports constructors
which create objects by executing code that allocates storage
for the objects and initialises all or part of them by
assigning initial values to their properties.

All constructors are objects, but not all objects are
constructors.

Each constructor has a Prototype property that is used to
implement prototype-based inheritance and shared properties.


这就是该帖子我起名字”不吐不快“的原因,对于清晰和精准地理解ECMAScript的语言机制是没有帮助的。

过去几年累积了不少ActionScript经验的我,现在看来这种的术语简直是混乱(mess caused by bad terminology)。

要列举这种混乱,从Flash5说起,那时MM公司是用ECMA-262实现ActionScript的,然后到Falsh7的时代,它们升级到ActionScript 2,基于ECMAScript4提案(未完成的)。

他们这样做的原因是因为他们想把”专业的“感觉赋予他们的软件,以吸引来自Java /C#等等环境的开发者。

结果令到人们相信ActionScript是真正的Class-Based语言,而不会去想他们的代码为 prototype-based(基于原型的) ,他们认为这样,仿佛就好像在编程Java或一些class-based一样。

这是彻底的错误 THIS IS PLAIN WRONG.

首先,我认为从一个未完成的草案,就去实现一门语言,是不负责的。只会引发前所未知的语言兼容性,从ActionScript和JScript.NET两个实现的差异有多大,就可以看出这种兼容性的问题,尽管都是来自同一个的草案。

第二,ECMA-262我们知道是基于原型的语言,也可以模拟class的行为,自身砍掉class-based本来没有的功能会有什么用呢?(译注:指原型的功能是“独有的”)

我给出一个我经历过的怪诞的例子,人们会把Java的思维方式放到ActionScript2:单列模式http://c2.com/cgi/wiki?SingletonPattern
这里是人们在ActionScript2实现该模式
class Singleton
     {
     private static var _oInstance:Singleton;
    
     private function Singleton() {}
    
     public static function getInstance():Singleton
       {
       if(_oInstance == undefined)
         {
         _oInstance = new Singleton();
         }
      
       return _oInstance;
       }
    
     public static function release():Void
       {
       if(_oInstance)
         {
         delete _oInstance;
         }
       }
   }
没错,他们是COPY JAVA的;是的,这并不对,这样做并不是Java不对,而是错在ECMAScript不是一个Class-based语言(正如边注所说,ActionScript2 不是真正的Class-based语言,只是写法上的Class-based)

基于原型的语言你所接触的是 对象 层次(work on the object level),你不需要为创建某个对象的实例去定义一个类,只是创建一个对象直接分配方法和属性即可。
   Singleton = {};
  
   Singleton.someProp = 12345;
  
   Singleton.someMethod = function( /*Number*/ num )
       {
       return this.someProp + num;
       }


那就是区别了,在java中得到单例,要实例化它,除了用class没有其它的方法。所以,在不规定的过程中,要保证该类只是实例化过一次,你会被规定使用类的getInstance方法,或类似的机制。

但是在ECMAScript中,你不需要为独一无二的对象实例化,你只需声明一下,因为你不需要 类 来实例化(甚至 构造器constructor),并向你保证这的确是独一无二的。

再引用:
 
引用
not all objects are constructors


在ECMAScript中用正确的术语是很重要的(译注:溯本清源???),使得人们不会用class-based的概念理解,也不会在相同的逻辑(如java)上犯糊涂。


你思考这些的代码时,尽可能不用class理解,而用对象去理解,理解这些对象,仅仅是字面上的理解,或有别于 class-based语言的内建构建函数创建出来, 又或者“当”它们是一样的,只是依靠内部机制创建而已,--但根本不一样。


欲真正理解基于原型的机制,请阅读论文解释细节http://www.idt.mdh.se/kurser/cd5130/msl/2005lp4/downloads/reports/prototype_based_languages.pdf

基于原型的语言的中心思想,是允许创建不需要类的对象,因此,请恕我直言,在ECMAScript之内不要使用 类 的术语。

References:
Prototype based languages
Billborn and Mallela Srinivasa Rao
PDF(if this document get moved, contact me to have a copy, I keep everything)
Raising Hell http://www.vh1.com/artists/az/run_dmc/77028/album.jhtmlRun-D.M.C. - Raising Hell (1986/1/1)
----------------------原创翻译---------------------------
虽然文章不是最新(快两年了),但观点较新颖,特此摘录翻译。如有纰漏恳请补充。
============================================
   发表时间:2007-06-02  
该文的大意,
和YUI剧院的上DC开头讲述Advanced JavaScript的观点
应该差不多
0 请登录后投票
   发表时间:2007-06-02  
补充一评论
I agree with your general message, but your language is off when you say "in ECMAScript, you do not need to instanciate your unique object, you just have to declare it."

In fact, you do need to instantiate it, because in ECMAScript, there are no classes, only instances. You get inheritance by setting an object's "prototype" pointer to another object, which then acts like a superclass -- the prototype object handles any methods not overridden by the object referencing it.

You can declare variables by saying "var x;" and so on, but that does nothing towards setting up a hierarchy of objects.
0 请登录后投票
   发表时间:2007-06-03  
pseudo-classes译为伪类更为恰当。当然理解上并没有太多的区别。

作者看起来对类很反感,实际上是对术语混乱和使用者的误用感到不满。也许是面向对象的思想有太强的侵入性,更甚者把它当作一把尺子去衡量其它语言。这本身就是错误的。

用封装、继承和多态作为标准评判是否面向对象,基于Prototype的语言如JavaScript被认为是OO语言。这对基于Prototype的语言多少有些不公。基于Prototype的语言也强调对象。一切都是对象,Array是对象,函数是对象,对象还是对象。对象无处不在。Prototype也是对象。Prototype实现了一种与基于类的面向对象语言不同一种对象表达方式。

首先,对象的创建方式不同。
Java或C#语言中,对象只能也仅能从类创建。而JavaScript对象的创建可以是临时组装、从函数创建、从Prototype共享constructor(也就是继承)等方式。

也就是说,Java中对象只能通过new创建,JavaScript则不一定。

其次,JavaScript没有类,所以不区分对象(或实例)和类。
0 请登录后投票
   发表时间:2007-06-04  
不得不说这个帖子真的很老,以至于我现在都连不到原文了。。。但是我的意思是,他的想法也蛮经典,2年前甚至更早我也是这样想的。当时我时不时在各个论坛里不厌其烦的传播prototype编程的精义。

但是现在我的想法有所变化,因为ECMAScript4的进展,确认OO的必要性,特别是由JS的创造者也认同这是一个合理的要求。已经有太多JS高手质疑混合prototype-based和class-based的ES4,但是语言标准制定者们仍义无反顾的在向前走。特别是他们不是学术委员会,而是业界久经考验的实践人士,以Adobe(Macromedia)和Mozilla为核心,尽管我心中仍充满疑惑,但不得不反思,他们确实是获得了大量支持向class-based前进的用户反馈。

关于术语,确实应该谨慎一些,但死扣被批判n多的ECMA262规范,未尝不是有点教条主义呢?譬如我们现在明确的叫js中的函数为closure,但是spec中也没有这个词不是么?关于“类”的时候,我觉得确实需要明确的是,ES3是没有语言机制意义上的类的,但是说以惯用法为基础的prototype继承,或者各种toolkit所提供的OO机制(如dean的Base),就一定不能称“类”,偏要每次都澄清一下,“我不是类,我只是长的像类”,未免又有一些迂腐了。

君不见ES3中的 new XXX() 的用法,不正是自己在冒充类么?BE自己说的清楚不过了,JS先天就是copy java的,虽然其骨子里是smalltalk/self/lisp……所以问题出在娘胎里,一昧责怪用户是不妥当的。
0 请登录后投票
论坛首页 Web前端技术版

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