《JavaScript 的诞生》

310 阅读8分钟

JS简介(来源维基百科):

JavaScript(通常缩写为JS)是一种高级的、解释型的编程语言。JavaScript是一门基于原型

、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编

程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持I/O,比如网络、存储和图

形等,但这些都可以由它的宿主环境提供支持。它已经由ECMA(欧洲电脑制造商协会)通过

ECMAScript实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器

(Chrome、IE、Firefox、Safari、Opera)支持。 

虽然JavaScript与Java这门语言不管是在名字上,或是在语法上都有很多相似性,但这两门编

程语言从设计之初就有很大的不同,JavaScript的语言设计主要受到了Self(一种基于原型的编

程语言)和Scheme(一门函数式编程语言)的影响。在语法结构上它又与C语言有很多相似

(例如if条件语句、switch语句、while循环、do-while循环等)。 

在客户端,JavaScript在传统意义上被实现为一种解释语言,但在最近,它已经可以被即时编

译(JIT)执行。随着最新的HTML5和CSS3语言标准的推行它还可用于游戏、桌面和移动应用

程序的开发和在服务器端网络环境运行,如Node.js。

JS历史:

肇始于网景

1993年,伊利诺伊大学厄巴纳-尚佩恩分校的国家超级电脑应用中心(NCSA)发表了NCSA 

Mosaic,这是最早流行的图形接口网页浏览器,它在万维网的普及上发挥了重要作用。1994

年,一家名为Mosaic Communications的公司在加州芒廷维尤成立了,并雇用了许多原来的

NCSA Mosaic开发者用来开发Mosaic Netscape,该公司的目标是取代NCSA Mosaic成为世

界第一的网页浏览器。第一个版本的网页浏览器Mosaic Netscape 0.9于1994年底发布。在四

个月内,已经占据了四分之三的浏览器市场,并成为1990年代互联网的主要浏览器。

为避免NCSA的商标所有权问题,该浏览器于同年更名为Netscape Navigator,该公司命名为

Netscape Communications。网景预见到网络需要变得更动态。公司的创始人马克·安德森认

为HTML需要一种胶水语言,让网页设计师和兼职程序员可以很容易地使用它来组装图片和插

件之类的组件,且代码可以直接编写在网页标记中。 

1995年,网景招募了布兰登·艾克,目标是把Scheme语言嵌入到Netscape Navigator浏览器

当中。但更早之前,网景已经跟昇阳合作在Netscape Navigator中支持Java,这时网景内部产

生激烈的争论。后来网景决定发明一种与Java搭配使用的辅助脚本语言并且语法上有些类似,

这个决策导致排除了采用现有的语言,例如Perl、Python、Tcl或Scheme。为了在其他竞争提

案中捍卫JavaScript这个想法,公司需要有一个可以运作的原型。艾克在1995年5月仅花了十天

时间就把原型设计出来了。 最初命名为Mocha,1995年9月在Netscape Navigator 2.0的

Beta版中改名为LiveScript,同年12月,Netscape Navigator 2.0 Beta 3中部署时被重命名为

JavaScript,当时网景公司与昇阳电脑公司组成的开发联盟为了让这门语言搭上Java这个编程

语言“热词”,因此将其临时改名为JavaScript,日后这成为大众对这门语言有诸多误解的原因之

一。

微软采纳

JavaScript推出后在浏览器上大获成功,微软公司在不久后就为Internet Explorer 3浏览器推出

了JScript,以与处于市场领导地位的网景产品同台竞争。JScript也是一种JavaScript实现,这

两个JavaScript语言版本在浏览器端共存意味着语言标准化的缺失,发展初期,JavaScript的标

准并未确定,同期有网景的JavaScript,微软的JScript双峰并峙。除此之外,微软也在网页技

术上加入了不少专属对象,使不少网页使用非微软平台及浏览器无法正常显示,导致在浏览器

大战期间网页设计者通常会把“用Netscape可达到最佳效果”或“用IE可达到最佳效果”的标志放

在主页。随着Internet Explorer 4的发布,微软引入了动态HTML的概念,但语言实现和不同专

有化的文档对象模型的差异仍然存在,成为网络上普及使用JavaScript的阻碍。

标准化

1996年11月,网景正式向ECMA(欧洲计算机制造商协会)提交语言标准。1997年6月,

ECMA以JavaScript语言为基础制定了ECMAScript标准规范ECMA-262。JavaScript成为了

ECMAScript最著名的实现之一。除此之外,ActionScript和JScript也都是ECMAScript规范的

实现语言。尽管JavaScript作为给非程序人员的脚本语言,而非作为给程序人员的脚本语言来

推广和宣传,但是JavaScript具有非常丰富的特性。

JS的是十个设计缺陷(以下内容来源http://www.ruanyifeng.com/blog/2011/06/10_design_defects_in_javascript.html):

1. 不适合开发大型程序

Javascript没有名称空间(namespace),很难模块化;没有如何将代码分布在多个文件的规范;允许同名函数的重复定义,后面的定义可以覆盖前面的定义,很不利于模块化加载。

2. 非常小的标准库

Javascript提供的标准函数库非常小,只能完成一些基本操作,很多功能都不具备。

3. null和undefined

null属于对象(object)的一种,意思是该对象为空;undefined则是一种数据类型,表示未定义。

  typeof null; // object

  typeof undefined; // undefined

两者非常容易混淆,但是含义完全不同。

  var foo;

  alert(foo == null); // true

  alert(foo == undefined); // true

  alert(foo === null); // false

  alert(foo === undefined); // true

在编程实践中,null几乎没用,根本不应该设计它。

4. 全局变量难以控制

Javascript的全局变量,在所有模块中都是可见的;任何一个函数内部都可以生成全局变量,这大大加剧了程序的复杂性。

  a = 1;

  (function(){

    b=2;

    alert(a);

  })(); // 1

  alert(b); //2

5. 自动插入行尾分号

Javascript的所有语句,都必须以分号结尾。但是,如果你忘记加分号,解释器并不报错,而是为你自动加上分号。有时候,这会导致一些难以发现的错误。

比如,下面这个函数根本无法达到预期的结果,返回值不是一个对象,而是undefined。

  function(){

    return
      {
        i=1
      };

  }

原因是解释器自动在return语句后面加上了分号。

  function(){

    return;
      {
        i=1
      };

  }

6. 加号运算符

+号作为运算符,有两个含义,可以表示数字与数字的和,也可以表示字符与字符的连接。

  alert(1+10); // 11

  alert("1"+"10"); // 110

如果一个操作项是字符,另一个操作项是数字,则数字自动转化为字符。

  alert(1+"10"); // 110

  alert("10"+1); // 101

这样的设计,不必要地加剧了运算的复杂性,完全可以另行设置一个字符连接的运算符。

7. NaN

NaN是一种数字,表示超出了解释器的极限。它有一些很奇怪的特性:

  NaN === NaN; //false

  NaN !== NaN; //true

  alert( 1 + NaN ); // NaN

与其设计NaN,不如解释器直接报错,反而有利于简化程序。

8. 数组和对象的区分

由于Javascript的数组也属于对象(object),所以要区分一个对象到底是不是数组,相当麻烦。Douglas Crockford的代码是这样的:

  if ( arr &&
    typeof arr === 'object' &&
    typeof arr.length === 'number' &&
    !arr.propertyIsEnumerable('length')){

    alert("arr is an array");

  }

9. == 和 ===

==用来判断两个值是否相等。当两个值类型不同时,会发生自动转换,得到的结果非常不符合直觉。

  "" == "0" // false

  0 == "" // true

  0 == "0" // true

  false == "false" // false

  false == "0" // true

  false == undefined // false

  false == null // false

  null == undefined // true

  " \t\r\n" == 0 // true

因此,推荐任何时候都使用"==="(精确判断)比较符。

10. 基本类型的包装对象

Javascript有三种基本数据类型:字符串、数字和布尔值。它们都有相应的建构函数,可以生成字符串对象、数字对象和布尔值对象。

  new Boolean(false);

  new Number(1234);

  new String("Hello World");

与基本数据类型对应的对象类型,作用很小,造成的混淆却很大。

  alert( typeof 1234); // number

  alert( typeof new Number(1234)); // object

关于Javascript的更多怪异行为,请参见Javascript Gardenwtfjs.com

如何看待Javascript的设计缺陷?

既然Javascript有缺陷,数量还不少,那么它是不是一种很糟糕的语言?有没有前途?

回答是Javascript并不算糟糕,相反它的编程能力很强大,前途很光明。

首先,如果遵守良好的编程规范,加上第三方函数库的帮助,Javascript的这些缺陷大部分可以回避。

其次,Javascript目前是网页编程的唯一语言,只要互联网继续发展,它就必然一起发展。目前,许多新项目大大扩展了它的用途,node.js使得Javascript可以用于后端的服务器编程,coffeeScript使你可以用python和ruby的语法,撰写Javascript。

最后,只要发布新版本的语言标准(比如 ECMAscript 5),就可以弥补这些设计缺陷。当然,标准的发布和标准的实现是两回事,上述的很多缺陷也许会一直伴随到Javascript存在的最后一天。