新时代新潮流 WebOS【16】作为浏览器方言的 JavaScript

2009-04-28 00:50

旧约-创世纪-第 11 章 1-9,(Genesis [11:1-9])

“1 那时,天下人的口音,言语,都是一样。2 他们往东边迁移的时候,在示拿地遇见一片平原,就住在那里。3 他们彼此商量说,来吧,我们要作砖,把砖烧透了。他们就拿砖当石头,又拿石漆当灰泥。4 他们说,来吧,我们要建造一座城和一座塔,塔顶通天,为要传扬我们的名,免得我们分散在全地上。5 耶和华降临,要看看世人所建造的城和塔。6 耶和华说,看哪,他们成为一样的人民,都是一样的言语,如今既作起这事来,以后他们所要作的事就没有不成就的了。7 我们下去,在那里变乱他们的口音,使他们的言语彼此不通。8 于是,耶和华使他们从那里分散在全地上。他们就停工,不造那城了。9 因为耶和华在那里变乱天下人的言语,使众人分散在全地上,所以那城名叫巴别(就是变乱的意思)。”

Douglas Crockford 以创世纪通天塔的故事为导言,开始了他对 JavaScript 的辩护。关于通天塔的读解有多种,一种读解是,神在警告人类不要狂妄,学 会谦卑。另一种读解是,这段话解释了方言的起源,没有其它隐喻。Douglas 把这段故事和计算机语言联系在一起,他说

“程序的核心问题在于驾驭复杂 性。在应对复杂多变的需求时,如果一个程序语言不能有助于驾驭复杂系统,那么结果就是混淆不清,接踵而至的就是失败。”

几十年来,人们设计了形形色色的计算机 语言,为什么不设计一种广为接受的,一统天下的语言,这样人们就可以把精力集中到这种语言的普及教育,并且设计开发各种工具,使这个世界通用语言变得功能 更加强大,使用更加简便?Douglas 说,“我们已经尝试过了,但是所有努力无一不以失败告终”。究其原因,当一个语言要处理的应用越来越多时,需要赋 予这种语言的功能也就越来越多,于是语言本身就越变越复杂,于是语言就越变越晦涩。

“所以,我们就看到大量的专门的语言出现。这些特殊语 种在应付特定范围的任务时,非常有效,这就足够了。当人们需要完成特定任务时,有合适的语言作为工具,这是天赐之福”。“语言设计的艺术在于知道如何取 舍。一个好的语言所拥有的诸多功能,能够和谐地互为补充共同工作。一个好的语言不仅能够帮助我们更好地理解问题,并且有益于找到解决方案的最佳表述方式。 ”

“一个好的语言的功能并不追求包罗万象,而是由有限的功能所组成。但是,哪些功能是有用的,哪些可以舍弃,却众说纷纭,没有统一意见。吸收哪些功能,让语言变得更加强大,这是永无休止的争论议题。并不是说功能不重要,问题在于我们不知道每个功能有多重要。”

Douglas Crockford Figure 2. Douglas Crockford

这位 Douglas Crockford 是 JavaScript 最知名的捍卫者,同时设计了 JSON,JSLint,JSMin 等等与 JavaScript 相关的构件和辅助工 具。JavaScript 的发明人 Brendan Eich 盛赞他是 Lambda 编程和 JavaScript 的精神领袖。Doug 不仅学问精湛,而且文采飞扬。Doug 对于语言有广泛的研究,其中特别热衷 于 Blissymbol 的推广。

二战时犹太人 Charles Bliss 逃难到了上海,在这期间他试图学习中文。一方面他认识到象形文字的优势,同时认为要记住数以万计的中文字,实在是一件难度很大的任务。于是,他 发明了几千个象形符号,以此为基础,通过组合这些基本的象形符号来表达复杂的概念。这就是 Blissymbol 的由来。Blissymbol 不仅可以表达 任何复杂的思想,而且非常容易学,甚至 “比学习自己的母语还要容易”。Doug 热衷于 Blissymbol,同时对中国也十分友好。

关于 JavaScript,Doug 写到,“大多数程序语言死于晦涩。只有少数语言,能够从一个项目组或者一个公司的试验品,扩散出去,吸引追随者。只有极少 数能够成为真正重要的语言。一门语言能否变得重要,有两条途径。第一个途径是体现某些重要的编程思想,或者提供实践这些思想的平台。Smalltalk 和 Scheme 就是通过这个途径走向成功的范例。虽然使用这些语言的人并不多,但是众口一词的评价是,它们的设计充满睿智,即便这种设计并不迎合时尚。虽然 它们本身并没有吸引很多使用者,但是对于未来的语言设计却具有深远的影响。另一个使一门语言变得重要的途径,是因为拥有众多用户而变得重要。在程序员选择 编程语言时,需要考虑的因素很多。但是用什么语言来编写浏览器脚本却无需左顾右盼,因为,至少目前而言,浏览器能够接受的编程语言,别无选择,只有 JavaScript。”

这真是一段坦荡得让人吃惊的评论。JavaScript 之所以重要,完全是源于它是众多浏览器唯一接受的语言。 换而言之,如果没有这样的垄断地位,JavaScript 也许就不会拥有如此众多的用户,没有众多的用户,而且也没有新颖的编程思想作为灵 魂,JavaScript 或许就不再是一门重要的语言。

Python,Ruby 等等语言是否能够替代 JavaScript 的地位呢?从技术上讲,是完全可能的。为什么 JavaScript 会占据垄断地位呢? Doug 的解释是这样的,与前面的论述一样,坦荡得令人佩服。

“为什么这样一个有着明显缺陷的语言,会成为 Web 唯一的编程语言呢?Brendan Eich 在 Netscape 任职的时候,成功地让他那个婆婆妈妈的领导,认识到 Navigator 浏览器需要一个脚本语言,而且只有重新发明一门新语言才 能胜任浏览器脚本这个工作。于是,一门新语言就开始匆匆忙忙地设计,匆匆忙忙地实现,而且压根就没有考虑是否能够延用现有的其它语言,去担当浏览器脚本这 个工作。事后不久,微软的 IE 浏览器项目组急于争夺 Netscape 的市场份额,他们逆向复制了 Netscape 的语言,全盘照抄,泥沙俱下。其它浏览器 开发商也追随微软的做法,盲目紧跟。并没有什么标准强制浏览器必须实现 JavaScript,但是 JavaScript 无意中成为各个主流浏览器的唯一的 通用的脚本语言。没有谁仔细深入地审视过这门语言本身,以及它所针对的问题范畴,也没有甄别它是否能够称职地解决这些问题,更谈不上设计是否完备。 Netscape 仓促中捏合了这门语言,然后它被复制到其它浏览器中去。当我们回顾 JavaScript 产生的背景,以及它成为事实上的 Web 编程语言的 标准的整个过程,我们有理由相信这门语言一定糟糕透顶。”

“尽管 JavaScript 存在惊人的缺陷,当我们深入分析这门语言的时候,会 发现其实它的内核,具有非常优秀的品质。当我们剥去污秽的外壳,JavaScript 的内里,是富于表现力的,功能强大的编程语言。这门语言被出色地应用 到很多 Ajax 函数库里,操控 XML-DOM,支持 Web 页面的交互,提供应用服务的平台。Ajax 之所以流行,是因为 JavaScript 不仅能够完成 任务,而且表现出色,令人惊讶。”

在 Doug 看来,JavaScript 的精髓在哪里呢?在 “JavaScript, the Good Parts” (published by O’Reilly) 这本书的第 10 章,Doug 列举了三条,

  1. Functions as first class objects
    作为一类对象,JavaScript 的函数可以像数值或者字符串那样,被动态地创建,存储,传输以及返回(return)。Java 的 method 不是一类 对象。一个 Java method 结束运算时,可以返回数值或者对象,但是无法返回另一个 method。C 的函数也不是一类对象,但是可以通过函数指针(function pointer)迂回达到类似功效,所以 C 的函数又被称为二类对象。
  2. Dynamic objects with prototypal inheritance
    在大多数 Object-Oriented 语言里,既有 class,又有 object,class 是 object 的抽象蓝图,规定了属性和函数。譬如你我他都 是人,但凡是人都有头脑和四肢,这就是属性,但凡是人都能做一些思考和运动,这就是函数。但是 JavaScript 取消了 class,所以在 JavaScript 的语汇里,不存在 “人” 这样抽象的 class,JavaScript 从不说 “他是一个人”,而只是说 “他与我很像”。
    取消 class 的好处在于精简了语言的复杂性,但是麻烦在于套用设计定式(design pattern)时,JavaScript 就显得比较笨拙。Doug 的文章成功地说服了大家,并不是 JavaScript 语言本身在表述 Design pattern 时显得笨拙,而是我们大多数人更习惯于传统的 OO 语言,习惯于既有 class 也有 object,而不习惯于没有 class 的情况。
  3. Object literals and array literals
    JavaScript 表述 object 和 array 的方式非常简练,同时这种表述方式使 object 和 array 的数据读取,编辑以及其它操作也干净利索。这种表述方式,直接促成了 JSON 数据传输格式的产生。

Doug 的三条分析都对,但是斗胆冒犯一句,似乎没有搔到痒处。正如前文中 Doug 坦率承认的那样,JavaScript 的卖点是对于浏览器的操控功能,而不是语 言本身的巧妙。但是令人失望的是,Doug 为 JavaScript 辩护的重心,在于区别 JavaScript 语言本身,与寄生于这个躯体之上的污秽的附属 物。他说到,
“JavaScript 是一个令人惊叹的语言,但不是好得让人惊叹,而是糟糕得让人惊叹。这个令人惊叹的本质,成就了它的恶名。JavaScript 与 DOM,尤其是 DOM 那些既可怕又可恶的 APIs 纠缠不清。人们不清楚 JavaScript 与 DOM 的分界在哪里,人们喋喋不休地谈论如何改进 JavaScript,但是这些改进本身,对于 web 开发而言,与事无补。这个语言肩负着太多太多功能,其中包括很多彼此难以和谐共存的,以及设计时就存 在先天缺陷的功能。这个语言太冗长,就像约瑟夫皇帝评论 Mozart 的音乐那样。”

所以,Doug 辩论的目的,是要还 JavaScript 一个清白,找还清白的方式,是剥离寄生于 JavaScript 的内核的 DOM 操控,HTML 事件处理等等,彼此难以和谐共存的,以及设计时就存在先天缺陷的那些功能。

问题是,即便我们有了一个脱离污秽的冰清玉洁的 JavaScript,充其量,我们又多了一个比 Python 和 Ruby 更好的脚本语言。但是这不是我们所需要的,我们需要的是如何高效地操控浏览器,换句话说,我们需要的正是那些污秽的附属物,具体说来,

  1. 如何捕捉发生浏览器页面的事件,譬如鼠标移动,点击和输入等等,对应 DOM-tree 的哪一个节点。
  2. 如何修改编辑 DOM-tree,尤其是多个节点或者子树的相关互动。
  3. 如何调用浏览器外部函数,以及如何让外部函数调用浏览器内部指令。

Brendan Eich 当年游说 Netscape 的领导时说得对,当时没有哪一个现成的语言具有上述功能,与其扩充现有语言的功能,不如另行发明一个新的语言,这个新的语言就是 JavaScript。

我们今天反思 JavaScript 的目的,并不是讨论这门语言好不好,如何改进。我们要大胆地问一句,究竟有没有必要存在这门语言,对于操控浏览器而言, 或许我们需要的是 protocol,而不是 language。如果说互联网浏览器的历史积淀很沉重,积重难返,那么对于手机浏览器而言,大可轻装上阵,不 必重蹈历史的覆辙。

后评论

评论在审核通过后将对所有人可见

正在加载中

移动互联网的围观者、起哄者、以及肇事者。

本篇来自栏目

解锁订阅模式,获得更多专属优质内容