詳圖實證:再談JavaScript的語源問題

作者: aimingoo  發布時間: 2012-06-08 17:25  閱讀: 2946 次  推薦: 1   原文鏈接   [收藏]  

  本文發布于2011-08-02

  有兩個錯誤的觀點,其一是“JavaScript在語源上繼承自Cmm”。這個錯誤的觀點主要的來自于以下途徑(部分):

  • 2002年10月7日的《Wired Magazine(連線雜志)》的一份名為“Mother Tongues”的圖;
  • O’Reilly公布的“The History of Programming Languages圖;
  • Levenez.com公布的“Computer Language History”;
  • ……

  第二個錯誤的觀點,即“Nombas公司的Espresso Pages(濃咖啡版網頁)以及其內置的腳本(CEnvi,Cmm語言的開發環境)是WWW上首次使用的腳本語言”。這個錯誤的觀點主要來自于:

  • 在Nombas網站中關于Cmm、CEniv以及ScriptEase等技術與產品的一篇介紹文字;
  • Brent Noorda先生(Nombas公司總裁)關于發布Espresso Pages的新聞組消息。

  這些明顯是不太靠譜的一面之詞。但是進一步援引這些內容的結果是:錯誤的觀點被一再重述,似乎已經快要變成事實了,例如《JavaScript高級程序設計》一書已經白底黑字地將這些內容記述在了“JavaScript簡史”之中。

  本文將簡明而完整地厘清上述觀點。

  一、真相:Netscape早在Espresso Pages發布之前就實現了主要的WEB開發特性

  首先,這些問題的一部分相當容易說清楚,例如“是不是Espresso Pages首次在WEB中使用了腳本語言”。因為關于Espresso Pages的這個新聞組消息還有著明確的時間(1995.11.27)(*1):

  那么,Netscape Navigator 2.0中對腳本的支持又是如何出現的呢?考察NN2此前發布的各個Beta版就可以發現(*2):至遲到NN2 Beta2,網頁內嵌腳本的概念就相當清晰,并且實現完整了。我們先看看在1995.10.10發布的NN2 Beta1這個版本。它能做什么呢?它其實已經具備了標簽內聯腳本功能,如下圖所示:

  相對完整的腳本特性,例如<script>標簽與function函數等,則要等到NN beta2才支持,其發布時間為1995.11.04:

  上面的示例說明了beta2中的腳本已經開始支持在函數內通過this引用來得到window對象,而frames、self這些成員在這時的window對象中就已經存在,這些事實上就是最最原始的DOM。

  所以,盡管Nombas是搶在了Netscape Navigator 2.0正式發布(1996.01.23,JavaScript 1.0隨該版本發布)之前,公開了在NN2上嵌入第三方腳本引擎的方式來實現的Espresso Pages,但是與我們今天討論的Web開發相關的一切,在這之前、在NN Beta2中就已成事實了。而這個Netscape Navigator Beta2的發布時間,比Espresso Pages的發布早了近一個月。

  《JavaScript高級程序設計》一書中不但認為Espresso Pages是WWW上“首次使用腳本語言的標志”,還繼續講道:

相信當初的Nombas公司不太可能意識到,他們這種網頁中嵌入腳本的想法會在很大程度上左右未來因特網的發展。

  這段“文字游戲”很容易讓讀者將“網頁嵌入腳本”的設想歸功于Nombas,以及具體的那個腳本語言Cmm。但如同上面所說的,這種設想并非源自Espresso Pages。這些想法的確左右了因特網的發展,但是沒有任何證據顯示Nombas與這一起源存在關系。

  二、真相:Cmm與JavaScript完全無關,而ScriptEase不過是追隨者

  Cmm的確是一種腳本語言,比JavaScript出現得早很多。但這個腳本語言并不是嵌入式的,它需要一個名為CEniv的可執行程序,來運行這種擴展名為.cmm的腳本代碼文件。因為Cmm一開始并沒有設計為嵌入式語言,所以這些稱為Espresso Pages的東西其實是一些可供下載的Demos,使用者需要安裝CEnvi的某個版本,并通過一些配置來使Demo能在NN2 beta中使用。原文是:

but for now these demos use our CEnvi for Windows application as a helper. Instructions are on the page for how to configure, including a download of a demo of the Cmm interpreter.

  現在已經再也找不到這些下載和操作指南了。不過我們這里并不想考察Espresso Pages的效果,而是想說清他當時所使用的Cmm語言與JavaScript語言有沒有什么關系。因為當時JavaScript正在開發之中,而Cmm已經出現了三年之久,那么JavaScript的語言設計是否參考了Cmm呢?

  目前可以下載到的CEnvi包括以下版本:

CEnvi 1.0                        – 1993.08.09

CEnvi 1.008                     – 1993.12.21

CEnvi 1.009 for DOS/Win/OS2    – 1994.11.29

CEnvi 2.0 for DOS/Win/OS2      – 1995.03.29

CEnvi 2.10 for DOS/Win/NT/OS2  – 1995.10.17

CEnvi 2.11 for DOS             – 1996.02.20

  在NN2之前的是CEnvi 2.0,NN2正式發布之后則有CEnvi 2.11。我們只需要考察這其中的Cmm語言的特性以及其進化的路線,就可以了解這一階段中二者可能存在的相互影響。根據Cmm的語言手冊(*3),其主要的發展為:

  • 1.0 ~ 2.0:添加了字符串中的轉義字符(Escape Sequences for Characters)
  • 2.0 ~ 2.1:無變化
  • 2.1 ~ 2.11:無變化

  也就是說,Cmm語言從1993年隨CEnvi發布一直到1996年2月,下面的語言特性并沒有任何實質性的變化:

  • 與C語言相似的運算符(包括位運算、布爾運符和三元”?:”運算符等)、注釋、字符串表達方式;
  • 有Byte、Integer、Float等數據類型,不需要預聲明變量,變量在第一次賦值時創建并關聯類型;
  • 有數組與字符串類型,數組不需要預定義長度或元素類型;字符串是字符類型的數組,可以通過數組下標存取;可以通過”...”方式,或用{...}聲明一系列單個字符的方式來聲明字符串;
  • 有結構(Structures)數據類型,用“.”字符存取其字段;
  • 有if、while、do、switch以及for等等語句,有GOTO語句;
  • 可以聲明函數,但不需要用function關鍵字開始,也不需要聲明參數類型,參數個數必須是確定的。
  • 有#include與#define等預聲明語句;在任意函數之外的代碼為初始化代碼,其聲明的變量為全局變量;在初始化代碼之后執行的第一個函數為main(ArgCount, ArgStrings)。

  可見Cmm語言的多數概念來自于C語言,而與JavaScript所體現的面向對象特性毫無關系。例如Cmm的數組是一個獨立的數據類型,取得數組的長度應使用GetArraySpan(aArr)函數,而不是取數組這個對象的一個屬性aArr.length。通過對Cmm語言特性的詳細分析可見:即使JavaScript與Cmm存有一些相似的部分,那么最多也是其借鑒自C語言的表達式運算、語句語法等等,而這些并不足以成為“JavaScript語源自Cmm”的證據。

  而在這個話題中的另一個角色,是名為“ScriptEase”的腳本語言,它也是最早符合ECMAScript 262標準的語言之一——簡單的說,它也是一個JavaScript語言。而且,Nombas公司正是因此將Cmm與JavaScript掛上關系,因為他們聲稱:ScriptEase就是Cmm,只不過是換了個名字。

  真的只是換了一個名字這樣簡單嗎?

  此前我們說過,Cmm的最后一個可見的發布包含在CEnvi 2.11中,發布時間是1996.02.20,其語言特性與上述列表一致(沒有變化)。這個語言是什么時候更名的呢?答案是:晚于1997.02.06。因為在1997年4月至6月間,Nombas公司發布了CEnvi的3.0版本,在這個版本中首次使用到ScriptEase這個名字,其中的名為HISTORY的文件——該文件被打包的時間(令人驚奇地)是1997.02.06——描述這次更名的緣由:

  那么在這個版本中的ScriptEase又具有什么樣的語言特性呢?答案是:與Cmm 1.0~2.11相比仍然沒有變化。對比該ScriptEase 3.0發布包中的語言手冊《The ScriptEase Language》與Cmm 2.11中對應文檔可知:數組、字符串、函數、GOTO語句等等一切,仍跟Cmm中一模一樣。

  但是這個原來叫Cmm的語言搖身一變,改名叫ScriptEase了。現在,請看下面這樣的代碼(語言手冊對比,左側為ScriptEase 3.0 - 1997.04.15文檔,右側為Cmm 2.11 – 1996.02.20文檔):

  相信任何一個看過JavaScript代碼的人都會明白,這個名為Cmm/ScriptEase的語言,所采用的函數聲明的語法絕非JavaScript語法,也絕對不可能符合ECMAScript所定義的規范。而此時已是1997年,JavaScript 已經發布了兩年,ECMAScript標準已即將發布(1997.06)。雖然現在的Cmm已經更名為ScriptEase,但在其語言手冊中仍然找不到Object這樣的詞匯,代碼上仍然使用著最初的函數聲明語法。

  那么,這樣的一門語言又是何時搖身一變,以至于被誤認為“JavaScript的語源”的呢。這一時間還要推進到半年之后,也就是1997年12月。這時ScriptEase發布了它的4.0版,在目前可以找到的一個名為“ScriptEase:WebServer Edition 4.01 – 1997.12.08”版本中(準確的說,我并沒有找到3.0至4.0的全部發布過程),終于有了一份手冊,開始采用如下的語法:

  正是在這份ScriptEase官方手冊中,寫道:

  現在這一切還需要解釋嗎?以下兩個言論:

  • ScriptEase在從3.0到4.0的過程中,采用了ECMAScript標準,進而實現了JavaScript的一個版本;
  • JavaScript語源自Cmm,繼承了后者語言特性

  之中,后者是何等的站不住腳?!然而,它正是這樣地畫在了O’Reilly的圖冊里(*4):

  三、真相:Nombas公司的廣告做得太好

  大概是2001年前后,Nombas官方網頁對其ScriptEase的介紹中,使用著一份名為“History of ScriptEase and JavaScript”的文檔(*5),但這個網頁使用著與該文檔標題完全不同的TITLE圖片:

  這篇文章的序言寫得中規中矩。大意是說1992年到1993年間,Nombas開發了一個Cmm語言。不過這里講到了該語言是“embeddable scripting language”,如前所述,這時的Cmm并沒有嵌入式的特性。但是從后來Nombas總是同時發布CEniv的不同操作系統平臺版本來看,Cmm語言是采用了跨平臺的語言(例如C)編譯的。而“Cmm隨CEnvi發布不同平臺版本”并不能作為它“具有嵌入特性”的充分證據。再退一步來看,即使Cmm具備了嵌入式語言特性,可作為獨立模塊來嵌入到CEnvi發布,也并不表明它可以嵌入到后來的Netscape Navigator中,因為后者在當時是閉源的,沒有可能讓CEnvi來“嵌入”。

  然而這一點,在《JavaScript高級程序設計》中被寫成:

When the popularity of Netscape Navigator started peaking, Nombas developed a version of CEnvi that could be embedded into web pages.

(在Netscape Navigator受到人們的狂熱追捧之際,Nombas公司開發了能夠嵌入到Web頁面中的CEnvi版本。)

  可惜這并非事實。關于這一點,Nombas的原文是:

When Netscape's first commercial browsers were released we made a version of CEnvi that could handle short scripts embedded within web pages.(當Netscape的第一個商業瀏覽器發布時,我們創建了一個嵌入在WEB頁面中的、能夠操作簡短腳本的CEnvi版本。)

  Nombas并沒有在這里指明“first commercial browsers”是Netscape的哪一個具體版本。因此這段文字很容易讓人誤解為NN 1.0發布的時候,CEnvi就已經可以實現網頁內嵌腳本了。而事實上,所謂的“CEnvi定制版本”根本就沒有出現過,即使曾經有過,也不過是Nombas在NN 2.0 beta中玩的一些小手腳。進一步地說,這時的Cmm、CEnvi以及后文中的"Espresso Pages",都只是Nombas在NN 2.0 Beta發布階段的一些技術嘗試而已。

  然而,這篇Nombas的原文又繼續談論“網頁內嵌腳本”的一些特點。例如:

By embedded scripts within the page we allowed the client side to handle processing, rather than making all dynamic interaction happen on the server. This brought immediate client-side interaction with the user.(使用網頁中的嵌入腳本,我們允許客戶端控制一些東西,這比讓所有動作發生在服務器端更好。這強化了客戶端與用戶之間的交互。)

  這些特性描述也就僅僅是對這類技術的一個概述而已,并不表明什么有“原創”、“獨創”或“初創”的意義(注意這段文字的未尾使用了“句號”)。但是接下來,Nombas耍了一個小花招,在文章中說:

The advantages of client-side handling were made obvious by Nombas' "Espresso Pages", and Netscape soon began work on their own version, which they called LiveScript, and then renamed to JavaScript just before its final release.(Nombas的"Espresso Pages"使客戶端控制的優勢更加明顯,接下來(and?)Netscape很快在他們自己的版本上開始工作,他們稱之為LiveScript,然后就在正式版本之前更名為JavaScript。)

  注意,“Netscape很快在他們自己的版本上開始工作”之前的“and”,這里可以理解為“接下來”,或者“并且”,或者僅僅是語氣上的連貫,但無論如何,這此前一個“逗號”便暗示了“their own version(他們自己的版本)”與前面所述的一切存在“必然的”關系。然而如本文此前所述的:

  • “Espresso Pages”中網頁內嵌腳本的想法,在NN Beta2中就已經成熟了,而后者早前了一個多月就發布了,談不上受到了“Espresso Pages”的影響。

  同樣的,正是由于這個“and”以及逗號,使得LiveScript與后面的JavaScript“變成了”Cmm的一個后來者,被錯誤地解讀成了“存在語源上的關系”。而本文此前的分析說明:

  • 事實上是Cmm受到了JavaScript的影響:ScriptEase在從3.0到4.0的過程中,采用了ECMAScript標準,進而實現了JavaScript的一個版本。

  正是Nombas原文中的措辭,不可避免地讓人認為LiveScript是基于"Espresso Pages"思想的(或受到其影響的)一個版本,進而發展成為JavaScript。但是事實上:

  • JavaScript最早被稱為Mocha(魔卡),這是項目的代碼名。這個名字一直用到NN2.0 beta 2發布之前(95.11.04)——包括在beta 1中彈出的錯誤框上,還可以看到Mocha的名字。
  • NN2.0 beta2發布的時候使用了LiveScript這個內部名稱。
  • 隨后Netscape與SUN共同發布聲明(1995.12.04),正式啟用了JavaScript這個名字。直到NN2.0 beta4發布時(1995.12.20),其文檔與軟件界面中才開始統一使用JavaScript這個名字。

  這一切,與“Espresso Pages”是否出現,有什么樣的關系嗎?——毫無關聯!

  四、最后的定論,Brendan Eich的澄清

  在Wiki Talk中保留著Brendan Eich的一段對話(*6),足以為Cmm與JavaScript之間的關系做最終的澄清。

Hello. I first met Brent Noorda in late 1996, when Netscape brought JavaScript to ECMA for standardization. I had never heard of NOMBAS or its products before then. When I created JS in May 1995 (in about ten days for the core language implementation; the rest of that year was consumed by the DOM and browser embedding work), my influences were awk, C, HyperTalk, and Self, combined with management orders to "make it look like Java."

  其一是與Cmm/Nombas的關系:

我第一次見到Brent Noorda是在1996年底,……在此之前我從未聽說過NOMBAS或它的產品。

  其二是JS語言的創建過程,以及大概的時間:

在1995年5月開始創建JS的時候(大約10天用于核心語言實現,其它的時間主要是用在DOM以及瀏覽器嵌入方面)。

  其三是關于JS語源的最終結論:

我的影響主要來自于awk、C、HyperTalk和Self,以及主管們所要求的“使它看起來像Java一點”。

  關于第三點,JavaScript“像”Java,而不是“語源自”Java,可以由《JavaScript Working Document 1.0》(1996.01.22),以及其原始的、Netscape公司的官方文檔《JavaScript Authoring Guide》文檔中的原文(*7):

The JavaScript language resembles java, …

  以佐證。JavaScript在語法上與Java、Awk和Perl都有一定“形似”,這可以由《JavaScript Language Specification V1.1》(1996.11.18,Brendan Eich參與編訂)文檔中的原文(*8):

Borrows most of its syntax from Java, but also inherites from Awk and Perl

  以佐證。最后,關于Brendan Eich所言:

my influences were awk, C, HyperTalk, and Self

  其中的關鍵語言特性——原型繼承、動態類型和動態數據綁定等,并未出現在Netscape Navigator 2.0及其中的JavaScript 1.0中,因此這里不再詳究。 

  參考:

  *1:http://embedded.eecs.berkeley.edu/Respep/Research/dds/Hyper-RNweb/0052.html

  *2:關于Netscape Navigator 2.0,其Beta版的發布時間采用安裝包文件的打包時間,其正式版的發布時間采用官方公告時間。

  *3:關于Cmm語言的特性與版本變更的相關結論,是通過對照各個CEnvi版本中的Cmm語言手冊(CEnvi Demo Manual, Chapter 2: Cmm Language Tutorial)而得出的。

  *4:http://oreilly.com/news/languageposter_0504.html

  *5:http://www.nombas.com/us/scripting/history.htm

  *6:http://en.wikipedia.org/wiki/Talk:ECMAScript#Origins_of_LiveScript

  *7:http://tecfa.unige.ch/guides/js/js10.pdf

  *8:http://www.planetpdf.com/codecuts/pdfs/tutorial/jsspec.pdf

  相關文章:還原JavaScript的真實歷史

1
0
 
標簽:JavaScript
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()