1. 需求推动创新
最开始,94年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器,但是只能用来看,而不像现在这样可以通过点击或者键盘输入来进行与用户的交互操作,所以在当有了这些需求的时候,就促使了一个网络语言脚本的产生。
2. 借东风却借来了西北风
一开始网景公司内部有两个选择,一是利用现有的编程语言,二是开发一种全新的但高度可根据自身定制的语言, 与此同时Sun公司开发的Java语言大火,遂与Sun公司结成同盟,开始推广在浏览器内使用Java语言,但最后由于使网页过于复杂而放弃。
3. C语言和Self语言一夜情的产物
到了95年4月的时候,网景公司聘用了一个叫Brendan Eich的系统程序员,因为公司还是想蹭Java的热度,但鉴于Java的语言复杂性,所以想发明一个简化版的Java语言,让非专业网页制作人员也能很快上手,但Brendan Eich本人对Java语法非常不感冒,所以应付花了10天时间,设计了一个JavaScript出来,也就是现在用的最初版本,他借鉴了C语言的基本语法,借鉴Java语言的数据类型和内存管理,借鉴Scheme语言,将函数提升到"第一等公民"(first class)的地位,借鉴Self语言,使用基于原型(prototype)的继承机制。当然,这个版本有很多的混乱,也不够严谨,经过后期的不断完善才有了现在的JavaScript。
4. 当代的视角来反省
4.1 给缺陷找点借口和理由
- 设计仓促,才10天时间,就创造了一门语言,并且设计初衷也仅仅是为了解决一些简单的网页互动(比如,检查"用户名"是否填写),并没有考虑复杂应用的需要。设计者做梦也想不到,Javascript将来可以写出像Gmail这种极其庞大复杂的网页。
- 凭空创造没有可以借鉴的东西,因为同时结合了函数式编程和面向对象编程的特点
- 规则标准的制定迫于为了压制当时的微软,所以语言没有经过充分的市场验证和问题暴露就被当成了标准制定成了国际标准。
4.2 细数缺陷
-
开发大程序比较不方便
因其没有命名空间,难模块化,缺乏当代码分布不同文件内时的规范,同名的函数会被允许重复定义,这就导致了后定义的函数会覆盖前面的定义,不利于模块化进行加载 -
标准库小
和Java的标准函数库没法比,功能很少, 只能完成基本操作 -
容易混淆的null和undefined
null属于对象(object)的一种,意思是该对象为空;
undefined则是一种数据类型,表示未定义。
在编程实践中,null几乎没用,根本不应该设计它。
-
难以控制的全局变量
Javascript的全局变量,在所有模块中都是可见的;任何一个函数内部都可以生成全局变量,这大大加剧了程序的复杂性。 -
谜之行尾分号
如果你忘记在每一行语句的结尾加分号,解释器并不报错,而是为你自动加上分号,但有时会令你得到意想不到的结果:
function(){
return
{
i=1
};
}
猜猜会得到什么?
返回值不是一个对象,而是undefined。
function(){
return;
{
i=1
};
}
因为自动加了分号,在return那里
-
不明确的 + 号操作,缺乏类型判断
两个数字类型会自动加和,两个字符串会自动 -
多此一举的NaN
NaN是一种数字,表示超出了解释器的极限
NaN === NaN; //false
NaN !== NaN; //true
alert( 1 + NaN ); // NaN
与其设计NaN,不如解释器直接报错,反而有利于简化程序。
-
想不到数组也是对象吧,哈哈
Javascript的数组也属于对象(object),所以要区分一个对象到底是不是数组,相当麻烦 -
谜之== 和 ===
==用来判断两个值是否相等。若两个值类型不同时,会发生自动转换,得到的结果非常不符合直觉。
"" == "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
推荐任何时候都使用"==="(精确判断)比较符。
- 基本类型的包装对象, 安能辨我是雄雌
Javascript有三种基本数据类型:字符串、数字和布尔值。
它们都有相应的建构函数,可以生成字符串对象、数字对象和布尔值对象。
new Boolean(false);
new Number(1234);
new String("Hello World");
alert( typeof 1234); // number
alert( typeof new Number(1234)); // object