JavaScript 10件让人费解的事情


Posted in Javascript onFebruary 15, 2010

1. 它以 Java 命名,但并不是 Java

它最初叫 Mocha, 接着改名为 LiveScript,最后才确定命名为 JavaScript,根据历史记录,Java 的命名与 Netscape 和 Sun 之间的合作有关,作为交换条件,Netscape 在他们备受欢迎的浏览器中创建了 Java 运行时。值得一提的是,这个名字的出台几近一个玩笑,要知道,LiveScript 和 Java 在客户端脚本方面存在敌对关系。

不管怎么说,人们后来不得不一再澄清的一件事就是,JavaScript 和 Java 毫无关系。

2. Null 是个对象?

看看这段代码,它返回的是 object。

JavaScript 10件让人费解的事情

这实在令人费解,假如 null 表示空值,它怎么可以是对象?简单说,它是 JavaScript 最初版本的错误,这个错误甚至被微软的 JScript 直接借用。

3. NaN !== NaN

NaN,表示一个非数字的值,然而问题是,NaN不等于任何东西,甚至不等于它自己。

JavaScript 10件让人费解的事情

这显然不对,事实上,如果要判断一个值确实是 NaN,你需要用 isNaN() 函数。

4. 全局变量

对全局变量的依赖一直被视为 JavaScript 最坏的部分(ECMA 的 JavaScript 5 已经去掉了全局变量,请参阅 ECMA 推出 JavaScript 5 - 译者注)。对简单的页面,这无所谓,但复杂的页面,如果包含大量 JavaScript 脚本,你很难知道某个全局变量是在哪里声明的,如果几个全局变量不小心重名,就会引发错误。

5. 那些统统被探测为 Mozilla User-Agent 的浏览器

必须承认,事实上,这不是 JavaScript  的错,是各个浏览器有意为之。比如,以下是用 JavaScript 探测 Safari 时得到的结果:

JavaScript 10件让人费解的事情

是否注意到其中的第一个单词 Mozilla/5.0,为什么 Safari 会被探测为 Mozilla,尽管 Safari 后来已经纠正这一问题,但仍然不能解释为什么它们要这样误导开发者。事实上,你会发现,绝大多数浏览器把他们的 User Agent 设置为 Mozilla,答案要回到10年前,这更多是一种策略。

User Agent 是一段用来标识当前浏览器身份的字符串,世界上第一个浏览器 Mosaic, 曾这样标志自己:

JavaScript 10件让人费解的事情

这很合理,因此当 Netscape 出来的时候,它保留了 Mosaic 这个传统,还在后面添加了一个加密方式部分。

JavaScript 10件让人费解的事情

到目前为止,一切安好,直到 IE3 发布,当 IE3 发布的时候,Netscape 正如日中天,那时,很多服务器和程序已经部署了客户端探测机制,以便认出 Netscape,虽然现在看来,这很值得争议,但当时并没什么。当 IE 初次推出它们的 User Agent 标志的时候,是这个样子:

JavaScript 10件让人费解的事情

这让 IE 很被动,因为 Netscape 已经能被很多服务器识别,因此,开发者们干脆希望 IE 被误认为 Mozilla,然后,再单独加一个 IE 的标签。

JavaScript 10件让人费解的事情

如今,几乎所有浏览器都步 IE 后尘,将自己标识为 Mozilla,这大概是一种连锁反应。

6. 不一致的函数范围

参看以下代码:

JavaScript 10件让人费解的事情

foo(bar.method) 返回结果不同原因是,method 函数是被当作 windows 对象,而不是 bar 下的对象调用的。要解决这个问题,我们必须从传递的匿名函数中调用 bar.method() 。

7. 位操作符

JavaScript 和 Java 有不少共同之处,如位操作。

  • & - and
  • | - or
  • ^ - xor
  • ~ - not
  • >> - signed right shift
  • ??? - unsigned right shift
  • << - left shift

看看第一个 & 操作符,使用 && 应该更有效,因为 JavaScript 和 Java 不一样,JavaScript 没有整数,需要来回转换,因此,转换操作花的时间更长。

8. 太多的空值类型

诸如 null, false, undefined 一类的值几乎表示同样的意思,它们之间的不同又让人很迷惑。

9. 算术问题

虽然 JavaScript 包含很多算术操作,但你不妨运行一下下面的算式,".2+.4" 应该等于 ".6" 是不是,然而返回的确是 "0.6000000000000001"。JavaScript 在小数计算访问存在一些小问题。

JavaScript 10件让人费解的事情

为什么会这样?简单说,因为 JavaScript 使用 IEEE 标准进行二进制浮点运算,不过,对整数计算是没问题的。

10. 莫名其妙的代码错误

看看以下两段代码:

JavaScript 10件让人费解的事情

它们应该是一样的,只是 { 位置不同而已,是吧。然而我们再看下面的代码:

JavaScript 10件让人费解的事情

如果我们把其中的

JavaScript 10件让人费解的事情

换成

JavaScript 10件让人费解的事情

就会引发错误,这是因为 JavaScript 有一个功能,会纠正它认为错误的代码书写,它会自作聪明地在 return 这个词后面插入一个 ";" ,错误因此而生。

JavaScript 10件让人费解的事情

Javascript 相关文章推荐
jQuery 源码分析笔记(3) Deferred机制
Jun 19 Javascript
表单元素值获取方式js及java方式的简单实例
Oct 15 Javascript
Javascript继承机制详解
May 30 Javascript
jquery实现下拉菜单的手风琴效果
Jul 23 jQuery
详解angularjs获取元素以及angular.element()用法
Jul 25 Javascript
Vue自定义指令详解
Jul 28 Javascript
vue中本地静态图片路径写法
Mar 06 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
Oct 09 Javascript
微信公众平台 客服接口发消息的实现代码(Java接口开发)
Apr 17 Javascript
使用zrender.js绘制体温单效果
Oct 31 Javascript
Vue 中使用 typescript的方法详解
Feb 17 Javascript
Vue v-for中的 input 或 select的值发生改变时触发事件操作
Aug 31 Javascript
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
Feb 15 #Javascript
jQuery 处理表单元素的代码
Feb 15 #Javascript
jQuery 树形结构的选择器
Feb 15 #Javascript
jQuery 处理网页内容的实现代码
Feb 15 #Javascript
JS getMonth()日期函数的值域是0-11
Feb 15 #Javascript
不同浏览器对回车提交表单的处理办法
Feb 13 #Javascript
Jquery iframe内部出滚动条
Feb 11 #Javascript
You might like
PHP在获取指定目录下的目录,在获取的目录下面再创建文件,多平台
2011/08/03 PHP
Yii编程开发常见调用技巧集锦
2016/07/15 PHP
yii2高级应用之自定义组件实现全局使用图片上传功能的方法
2016/10/08 PHP
PHP单例模式简单用法示例
2017/06/23 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
PHP手机短信验证码实现流程详解
2018/05/17 PHP
IE之动态添加DOM节点触发window.resize事件
2010/07/27 Javascript
更换select下拉菜单背景样式的实现代码
2011/12/20 Javascript
解决Extjs4中form表单提交后无法进入success函数问题
2013/11/26 Javascript
javascript 回到顶部效果的实现代码
2014/02/17 Javascript
javascript中attribute和property的区别详解
2014/06/05 Javascript
javascript框架设计读书笔记之字符串的扩展和修复
2014/12/02 Javascript
轻量级javascript 框架Backbone使用指南
2015/07/24 Javascript
HTML5 实现的一个俄罗斯方块实例代码
2016/09/19 Javascript
React Navigation 使用中遇到的问题小结
2018/05/08 Javascript
过滤器vue.filters的使用方法实现
2019/09/18 Javascript
详解关闭令人抓狂的ESlint 语法检测配置方法
2019/10/28 Javascript
vue组件传值的实现方式小结【三种方式】
2020/02/05 Javascript
Python获取暗黑破坏神3战网前1000命位玩家的英雄技能统计
2016/07/04 Python
使用Python实现跳一跳自动跳跃功能
2019/07/10 Python
python DataFrame转dict字典过程详解
2019/12/26 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
python实现mask矩阵示例(根据列表所给元素)
2020/07/30 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
2021/02/25 Python
使用css实现android系统的loading加载动画
2019/07/25 HTML / CSS
马来西亚最好的婴儿商店:Motherhood
2017/09/14 全球购物
J2EE面试题大全
2016/08/06 面试题
普通简短的个人自我评价
2014/02/15 职场文书
家长对老师的评语
2014/04/18 职场文书
世界环境日活动总结
2015/02/11 职场文书
2015年度优秀员工获奖感言
2015/07/31 职场文书
班主任工作总结范文
2015/08/13 职场文书
学习党史心得体会2016
2016/01/23 职场文书
JavaScript小技巧带你提升你的代码技能
2021/09/15 Javascript
Redis实现订单过期删除的方法步骤
2022/06/05 Redis