JavaScript的历史
参考文章:
《Code Rush》纪录片,记录了 Firefox 开源的过程和JS 之父的采访
一、从古代说起
1994年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器,轰动一时。但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力
因此,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。
1994年正是面向对象编程(object-oriented programming)最兴盛的时期,C++是当时最流行的语言,而Java语言的1.0版即将于第二年推出,Sun公司正在大肆造势。
Brendan Eich无疑受到了影响,Javascript里面所有的数据类型都是对象(object),这一点与Java非常相似。但是,他随即就遇到了一个难题,到底要不要设计"继承"机制呢?
二、Brendan Eich的选择
如果真的是一种简易的脚本语言,其实不需要有"继承"机制。但是,Javascript里面都是对象,必须有一种机制,将所有对象联系起来。所以,Brendan Eich最后还是设计了"继承"。
但是,他不打算引入"类"(class)的概念,因为一旦有了"类",Javascript就是一种完整的面向对象编程语言了,这好像有点太正式了,而且增加了初学者的入门难度。
他考虑到,C++和Java语言都使用new命令,生成实例。
C++的写法是:
ClassName *object = new ClassName(param);
Java的写法是:
Foo foo = new Foo();
因此,他就把new命令引入了Javascript,用来从原型对象生成一个实例对象。但是,Javascript没有"类",怎么来表示原型对象呢?
这时,他想到C++和Java使用new命令时,都会调用"类"的构造函数(constructor)。他就做了一个简化的设计,在Javascript语言中,new命令后面跟的不是类,而是构造函数。
举例来说,现在有一个叫做DOG的构造函数,表示狗对象的原型。
function DOG(name){
this.name = name;
}
对这个构造函数使用new,就会生成一个狗对象的实例。
var dogA = new DOG('大毛');
alert(dogA.name); // 大毛
三、new运算符的缺点
用构造函数生成实例对象,有一个缺点,那就是无法共享属性和方法。
比如,在DOG对象的构造函数中,设置一个实例对象的共有属性species。
function DOG(name){
this.name = name;
this.species = '犬科';
}
---
var dogA = new DOG('大毛');
var dogB = new DOG('二毛');
---
dogA.species = '猫科';
alert(dogB.species); // 显示"犬科",不受dogA的影响
这两个对象的species属性是独立的,修改其中一个,不会影响到另一个。
每一个实例对象,都有自己的属性和方法的副本。这不仅无法做到数据共享,也是极大的资源浪费。
四、prototype属性的引入
考虑到这一点,Brendan Eich决定为构造函数设置一个prototype属性。
这个属性包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。
由于所有的实例对象共享同一个prototype对象,那么从外界看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样。
这就是Javascript继承机制的设计思想。
五、JS的诞生
-
1995年Sun公司将Oak语言改名为Java,正式向市场推出。
-
Sun公司大肆宣传,许诺这种语言可以"一次编写,到处运行"(Write Once, Run Anywhere),它看上去很可能成为未来的主宰。
-
网景公司动了心,决定与Sun公司结成联盟, 网景公司的整个管理层,都是Java语言的信徒,Sun公司完全介入网页脚本语言的决策。
-
因此,Javascript后来就是网景和Sun两家公司一起携手推向市场的,这种语言被命名为"Java+script"并不是偶然的。
-
1995年4月,网景公司录用了此时34岁的系统程序员Brendan Eich。
Brendan Eich的主要方向和兴趣是函数式编程,网景公司招聘他的目的是研究将Scheme语言作为网页脚本语言的可能性。
-
1995年5月,网景公司做出决策,未来的网页脚本语言必须"看上去与Java足够相似",但是比Java简单,使得非专业的网页作者也能很快上手。这个决策实际上将Perl、Python、Tcl、Scheme等非面向对象编程的语言都排除在外了。
-
Brendan Eich被指定为这种"简化版Java语言"的设计师。
但是,他对Java一点兴趣也没有。为了应付公司安排的任务,他只用10天时间就把Javascript设计出来了。
- 由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间,Javascript写出来的程序混乱不堪。
六、他的设计思路
-
借鉴C语言的基本语法;
-
借鉴Java语言的数据类型和内存管理;
-
借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位;
-
借鉴Self语言,使用基于原型(prototype)的继承机制。
所以,Javascript语言实际上是两种语言风格的混合产物
(简化的) 函数式编程 + (简化的) 面向对象编程。这是由Brendan Eich(函数式编程)与网景公司(面向对象编程)共同决定的。
浏览器大战
- 1996年8月IE3发布,支持JScript;(微软实现的JS,统称山寨版JS)
- 浏览器大战开始,每家浏览器脚本都不一样。
- 1996年11月,网景向ECMA提交语言标准, 由于版权问题, JS语言标准不叫JavaScript, 叫ECMAScript
网景之死
- 微软的IE捆绑Windows很快占据市场
- 1998年,网景快死了,公司打算搏一搏,将浏览器开源(firefox)
- 1998年,市场并没有青睐网景,年底美国在线(AOL)宣布开始收购网景
IE6如日中天
- 2001年IE6随windowsXP一起发布
- 2004年IE6在全球市场占有率为80%
- 然而这款浏览器不兼容w3c标准,主要是不兼容css,同时ie6也不断爆出安全漏洞
- 2004年,firefox打算涅槃重生,打败ie6
- 2005年IE7发布,但市场主流还是IE6和firefox
- 2010年,中国的主流浏览器还是IE6
- XP在中国盗版风行,在很多年里,IE6始终占据中国浏览器市场,成为前端开发人员的噩梦。
Chrome的横空出世
IE6的巨大成功让微软飘了,解散了IE6团队,但Firefox的出现让微软重组IE团队,但不是以前的IE6团队同一组人,所以IE7,8一直问题不断。
谷歌觉的这是一个机会,于是雇佣了一些firefox和ie的开发者,经过数年研发:
- 2008年推出了Chrome浏览器,发布当年拿下全球1%的份额
- 2011年全球份额超过firefox
- 2016年,占全球市场份额的62%。
- 到2008年,Chrome终于发布,迅速拿下1%的份额;经过3年时间超越Firefox
- 于2016年已经占据全球市场的62%
Javascript的设计缺陷
一、为什么Javascript有设计缺陷?
- 设计阶段过于仓促
Javascript的设计,其实只用了十天。而且,设计师是为了向公司交差,本人并不愿意这样设计
- 没有先例
Javascript同时结合了函数式编程和面向对象编程的特点,这很可能是历史上的第一例。
- 过早的标准化
- 1995年5月,设计方案定稿;
- 1995年10月,解释器开发成功;
- 1995年12月,向市场推出,立刻被广泛接受,全世界的用户大量使用。
- 1996年11月,为了压制微软的JSstript,网景申请javascript的国际标准
- 1997年6月,第一个国际标准ECMA-262正式发布
Javascript推出一年半之后,国际标准就问世了。设计缺陷还没有充分暴露就成了标准。相比之下,C语言问世将近20年之后,国际标准才颁布。
二、Javascript的10个设计缺陷
参考文章: Javascript的10个设计缺陷
- 不适合开发大型程序
- 非常小的标准库
- null和undefined
- 全局变量难以控制
- 自动插入行尾分号
- 加号运算符
- NaN
- 数组和对象的区分
- == 和 ===
- 基本类型的包装对象
三、如何看待Javascript的设计缺陷?
Javascript并不算糟糕,相反它的编程能力很强大,前途很光明。
首先,如果遵守良好的编程规范,加上第三方函数库的帮助,Javascript的这些缺陷大部分可以回避。
其次,Javascript目前是网页编程的唯一语言,只要互联网继续发展,它就必然一起发展。目前,许多新项目大大扩展了它的用途,node.js使得Javascript可以用于后端的服务器编程,coffeeScript使你可以用python和ruby的语法,撰写Javascript。
最后,只要发布新版本的语言标准(比如 ECMAscript 5),就可以弥补这些设计缺陷。当然,标准的发布和标准的实现是两回事,上述的很多缺陷也许会一直伴随到Javascript存在的最后一天。