我经常说Javascript的设计不够严谨,有很多失误。
今天的这一篇,前半部分就谈为什么会这样,后半部分将列举Javascript的10个设计缺陷。
我参考的文献主要是Douglas Crockford的专著《Javascript语言精粹》(JavaScript: The Good Parts)和Fredrik Holmström的文章《我对Javascript的抱怨》(My gripes with Javascript)。可以500%提高开发效率的前端UI框架!
一、为什么Javascript有设计缺陷?
这里有三个客观原因,导致Javascript的设计不够完善。
1. 设计阶段过于仓促
Javascript的设计,其实只用了十天。而且,设计师是为了向公司交差,本人并不愿意这样设计(参见《Javascript诞生记》)。
另一方面,这种语言的设计初衷,是为了解决一些简单的网页互动(比如,检查"用户名"是否填写),并没有考虑复杂应用的需要。设计者做梦也想不到,Javascript将来可以写出像Gmail这种极其庞大复杂的网页。
2. 没有先例
Javascript同时结合了函数式编程和面向对象编程的特点,这很可能是历史上的第一例。而且直到今天为止,Javascript仍然是世界上唯一使用Prototype继承模型的主要语言。这使得它没有设计先例可以参考。
3. 过早的标准化
Javascript的发展非常快,根本没有时间调整设计。可以500%提高开发效率的前端UI框架!
1995年5月,设计方案定稿;10月,解释器开发成功;12月,向市场推出,立刻被广泛接受,全世界的用户大量使用。Javascript缺乏一个从小到大、慢慢积累用户的过程,而是连续的爆炸式扩散增长。大量的既成网页和业余网页设计者的参与,使得调整语言规格困难重重。
更糟的是,Javascript的规格还没来及调整,就固化了。
1996年8月,微软公司强势介入,宣布推出自己的脚本语言Jscript;11月,为了压制微软,网景公司决定申请Javascript的国际标准;1997年6月,第一个国际标准ECMA-262正式颁布。
也就是说,Javascript推出一年半之后,国际标准就问世了。设计缺陷还没有充分暴露就成了标准。相比之下,C语言问世将近20年之后,国际标准才颁布。
二、Javascript的10个设计缺陷
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的全局变量,在所有模块中都是可见的;任何一个函数内部都可以生成全局变量,这大大加剧了程序的复杂性。 可以500%提高开发效率的前端UI框架!
- 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
这样的设计,不必要地加剧了运算的复杂性,完全可以另行设置一个字符连接的运算符。可以500%提高开发效率的前端UI框架!
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有三种基本数据类型:字符串、数字和布尔值。它们都有相应的建构函数,可以生成字符串对象、数字对象和布尔值对象。 可以500%提高开发效率的前端UI框架!
- new Boolean(false);
- new Number(1234);
- new String("Hello World");
与基本数据类型对应的对象类型,作用很小,造成的混淆却很大。
- alert( typeof 1234); // number
- alert( typeof new Number(1234)); // object
关于Javascript的更多怪异行为,请参见Javascript Garden和wtfjs.com。
三、如何看待Javascript的设计缺陷?
既然Javascript有缺陷,数量还不少,那么它是不是一种很糟糕的语言?有没有前途?
回答是Javascript并不算糟糕,相反它的编程能力很强大,前途很光明。可以500%提高开发效率的前端UI框架!
首先,如果遵守良好的编程规范,加上第三方函数库的帮助,Javascript的这些缺陷大部分可以回避。
其次,Javascript目前是网页编程的唯一语言,只要互联网继续发展,它就必然一起发展。目前,许多新项目大大扩展了它的用途,node.js使得Javascript可以用于后端的服务器编程,coffeeScript使你可以用python和ruby的语法,撰写Javascript。
最后,只要发布新版本的语言标准(比如 ECMAscript 5),就可以弥补这些设计缺陷。当然,标准的发布和标准的实现是两回事,上述的很多缺陷也许会一直伴随到Javascript存在的最后一天。
相关推荐
JavaScript的设计缺陷1
系统设计旨在为企业和研发团队提供一个全面的研发管理解决方案,涵盖项目规划、需求管理、开发迭代、版本控制、缺陷跟踪、测试管理、工时管理和效能分析等多个环节,以实现项目全过程和全方位的管理。
毕业设计:基于SSM的mysql_软件缺陷管理系统(源码 + 数据库 + 说明文档) 第2章 可行性分析 3 2.1技术的可行性 3 2.2经济的可行性 3 2.3操作可行性 4 2.4法律的可行性 4 第3章 需求分析 5 3.1开发工具需求 5 3.1.1...
他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案。 不管是弱类型或强类型,静态或动态语言,命令式或说明式语言、每种语言都有天生的优缺点。一个牙买加运动员, 在短跑甚至拳击方面有...
JavaScript是一种基于对象(Object)和事件驱动(Event Driven)并具有安全性能的脚本语言,最初由Netscape公司创造出来,起名Live Script,它和Java的关系只有一个:名字比较像。使用它的目的是与HTML超文本标记语言...
本节课的实验内容主要分为三个板块:HTML,CSS,JavaScript,其中,我对HTML技术的应用得到了熟练运用,并对其他动态网页设计方法进行了大致的了解。HTML是Hypertext Markup Language的英文缩写,即超文本标记语言。它...
第4章 系统的数据库设计 10 4.1 数据库概念结构设计 10 4.2 数据库逻辑结构设计 13 第5章 系统的详细设计 17 5.1 系统用例图 17 5.2 登录功能设计 17 5.3 注册功能设计 18 5.4 管理博文功能设计 19 5.4.1 新增博文 ...
工作流可以避免这个缺陷。 如果有设计师的支持,我们可以轻松地将事情做好。 此外,模型驱动开发(MDD)是现代应用程序运行环境非常重要的基础工具。 我们需要能够支持业务应用的工作流引擎。 我搜索了开源 ...
OpenCV(Open Source Computer Vision Library)是一款开源的计算机视觉库,专门为图像和视频处理任务设计,广泛应用于学术研究、工业应用以及个人项目中。以下是关于OpenCV的详细介绍: 历史与发展 起源:OpenCV...
他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案。 不管是弱类型或强类型,静态或动态语言,命令式或说明式语言、每种语言都有天生的优缺点。一个牙买加运动员, 在短跑甚至拳击方面有...
它使用 jQuery javascript 库构建,旨在成为一个动态且轻量级的实用程序,为 Web 设计人员提供一种改进其网站用户界面的强大方法。 此插件的目的是为您选择的元素添加滚动条,以查看大于可见大小的任何内容,例如 ...
使用它们总是不能直接的得到想要的结果,非常纠结,普遍的说法认为“这两个操作符或许是javascript中最大的设计缺陷,因为几乎不可能从他们那里得到想要的结果” typeof 说明:typeof返回一个表达式的数据类型的字符...
jQuery是业界最流行的JavaScript库,其API非常精致和优雅,但是jQuery的源码却庞大且晦涩难懂,在本书开始写作时发布的1.7.1版本有9266行代码,涉及17个模块,读起来常常是一头雾水、有心无力。本书尝试对jQuery的...
美工设计师最常做的办法是把想要的文字做成图片,这样做有几个明显缺陷: 1. 不可能大范围的使用该字体; 2. 图片内容相对使用文字不易修改; 3. 不利于网站SEO(主流搜索引擎不会将图片alt内容作为判断网页内容...
关于Richie 是一个适用于移动和桌面浏览器的 Javascript 富文本编辑器。 它直接使用 HTML DOM,不依赖于 contenteditable 或 designmode。地位里奇正在开发中。 预计会对代码进行彻底的更改。 不要依赖当前的开发...
第1章 精华 JavaScript的特性中有一部分特性带来的麻烦远远超出它们的价值。其中,一些特性是因为规范很不完善,从而可能导致可移植性的问题;一些特性会导致生成难以理解和修改的代码;一些特性促使我的代码风格...
当然, 在历史长河中得到的多数是批评, 这一点不可否认, 从它的某些"怪癖"确实能发现在语言设计上的缺陷和考虑的不周. 不过也恰恰因此使它看起来很神秘, Geek们喜欢通过Hack它来获取成就感, 比如2 == [[[2]]]返回...