日期:2014-05-16  浏览次数:20397 次

详图实证:再谈JavaScript的语源问题

转自:http://blog.csdn.net/aimingoo/article/details/6654742

本文发表于《程序员》2011.03期】

?

有两个错误的观点,其一是“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):

Espresso pages的新闻

那么,Netscape Navigator 2.0中对脚本的支持又是如何出现的呢?考察NN2此前发布的各个Beta版就可以发现(*2):至迟到NN2 Beta2,网页内嵌脚本的概念就相当清晰,并且实现完整了。我们先看看在1995.10.10发布的NN2 Beta1这个版本。它能做什么呢?它其实已经具备了标签内联脚本功能,如下图所示:

NN2 Beta1中的JavaScript

相对完整的脚本特性,例如<script>标签与function函数等,则要等到NN beta2才支持,其发布时间为1995.11.04:

NN2 Beta2中的JavaScript

上面的示例说明了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等预声明语句;在任意函数之外的代码为初始化代码,其声明的变量为全局变量;在初始化代码之后执行的第一个函数为