《JavaScript高级程序设计》第3版与第2版有何差异

JavaScript010

《JavaScript高级程序设计》第3版与第2版有何差异,第1张

第3版全新的内容就有5章,涵盖了全新的HTML5 API,比如历史状态管理、Canvas、离线应用、Web Workers,等等。在全书各章里,我也增加了ECMAScript 5带来的变化,包括严格模式的限制和如何使用新API创建对象。原有内容也都更新了最新浏览器支持信息,包括移动平台浏览器的支持情况(不过,浏览器支持情况永远跟不上变化)。另外,这一版还为ECMAScript Harmony增加了一个附录,以便读者提前了解一下未来的情形。

译者在翻译过程中比对的信息

本书第2版正文22章,另有两个附录。第3版则有25章,4个附录。作者在博客中提到的新增的5章大致应该如下。

第11章:DOM扩展

第15章:使用Canvas绘图

第16章:HTML5脚本编程

第23章:离线应用与客户端存储

第25章:新兴的API

之所以说大致是这5章,主要因为它们跟“HTML5及相关规范”都有联系。而事实上,可以算得上新增的不止这几章,以下几章内容基本上也算是全新的。

第20章:JSON(介绍浏览器对JSON序列化及字符串解析的原生API)

第21章:Ajax与Comet(介绍Ajax及长轮询和HTTP流——Comet)

附录A:ECMAScript Harmony

附录B:严格模式

除此之外,更新内容比较多的还有以下几章——主要区别是ECMAScript 5新增的严格模式下一些基本语法结构的变化及限制,还有新的语言特性(比如新增的数组操作方法、事件类型等)以及DOM3级事件模块相关的更新:

第3章:语言基础

第5章:引用类型

第13章:事件

目前,本书正在翻译中。图灵会在保证质量的前提下,尽量加快本书的出版进度,希望这个体现ECMAScript 5和HTML5规范的新版本早日与中文读者见面。

思路:

你需要先组织默认的右键事件,

你需要自己制作一个右键图层,

下面是简单的代码:

<style>

* {margin:0 padding:0 list-style:none}

#ul1 li {width:400px background:#CCC border:1px solid black margin:10px float:left line-height:30px text-indent:1em}

#menu {width:150px border:1px solid black border:1px solid black position:absolute left:0 top:0 display:none background:white}

#menu li {padding:3px}

#menu li:hover {background:#CCC}

</style>

<script>

window.onload=function (){

var aLi=document.getElementById('ul1').children

var oMenu=document.getElementById('menu')

var aMenuLi=oMenu.children

for (var i=0 i<aLi.length i++)

{

aLi[i].oncontextmenu=function (ev){

var oEvent=ev || event

oMenu.style.display='block'

oMenu.style.left=oEvent.clientX+'px'

oMenu.style.top=oEvent.clientY+'px'

var _this=this

aMenuLi[0].onclick=function (){

_this.parentNode.removeChild(_this)

}

return false

}

}

document.onclick=function (){

oMenu.style.display='none'

}

}

</script>

</head>

<body>

<ul id="menu">

<li>删除</li>

<li>变成红色</li>

<li>变成绿色</li>

<li>变成黄色</li>

<li>变成蓝色</li>

</ul>

<ul id="ul1">

<li>中国信保原副总戴春宁贪污、受贿、通奸被开除党籍</li>

<li>中纪委原书记贺国强考察贵阳孔学堂(图)</li>

<li>解放军报官微:胡锡进相关微博内容是胡说八道</li>

<li>刘汉向湖北省高院提出上诉 已提交上诉状</li>

<li>澳洲公布疑似马航坠毁噪音 或解MH370失踪之谜</li>

<li>曝京沪高铁上海段地面开裂10cm 回应称不影响运营</li>

<li>朝鲜宣传一农场已建成“社会主义世外桃源”(图)</li>

</ul>

</body>

这一篇真的要说0.1 + 0.2 了。。

先来一个计算题来热热身吧。

我知道你想怎么做:362500 + 314 = 362814。没错,是这样算的,再来一个。

还用刚才的办法吗?还是算了吧,实在太长了,换一种办法:

运算法则不用多说了吧,这种方法还是很简单的,IEEE754浮点数也是使用这种办法计算的加法的,准确来说,是计算机中所有种类的浮点数都是这么计算加法的,因为浮点数标准可不只有IEEE一家才有。

现在借用工具把 0.1 和 0.2 的 64位浮点数格式表示出来。

图中上面的64位浮点数代表0.1,下面的64位浮点数代表0.2( 注意,因为计算时肯定是拿的内存中的值,所以此时的0.1 和 0.2 都是经过存储前舍入处理的了 ),并且已经列出了加法计算的5个步骤:

一. 阶码对阶

二. 尾数相加

三. 结果规格化

四. 尾数舍入处理

五. 溢出判断

那就按照顺序来一一说明。

首先,要把指数位(阶码)调整成一致才能计算加法,但是和开篇的计算题不同的是,这里规定必须是 小阶向大阶看齐 。

很明显,0.1的阶码比0.2的要小,所以0.1的尾数(小数位)向右移动一位,同时阶码 + 1。

点击下一步后如下所示:

因为阶码部分暂时已经确定,所以拿出来单独显示。

这一步比较简单,就是使用加法器把两个值相加,结果如下图所示。

还记得规格化是什么东西吗,联想一下科学计数法,计算后的尾数需要变成1.xxxx的形式,通过尾数的右移动来实现规格化,整体右移一位,阶码 +1。本案例中需要右移一位即可,所以阶码 +1。

舍入规则同第四章所说一致,可以返回 《JS基础-数字-0.1+0.2!=0.3(四)》 查看,当前命中了五取偶。

由于符合舍入规则五取偶中的 “如果X的值为1,则进1”,所以进1

溢出判断规则:

本案例没有命中溢出,所以不需要处理。

对比一下真正的0.3存入内存时的64位浮点数是什么样的:

细心的同学应该发现了其中的不同,0.1 + 0.2 的最终结果和 0.3 相比,在最后一位多进了一个1。这也就是为什么他们不相等的原因,0.1 + 0.2 已经不是 0.3 了。

首先,每一个IEEE754浮点编码都必须对应一个唯一的10进制的值,这是必须的,因为IEEE754没有规定每一个编码转化成的10进制的值必须是多少,但是却规定, 一个IEEE754浮点编码转化成10进制的值不做绝对限制,但当这个10进制的值在转化回IEEE754浮点编码时,必须还能还原成之前的IEEE754浮点编码。

如果 IEEE754浮点编码 0011111111010011001100110011001100110011001100110011001100110011 和 0011111111010011001100110011001100110011001100110011001100110100 都代表了0.3,那么当我存储0.3时,要转化成这两个编码的哪一个呢?

其次,如果如你所想的这么干了,0.3 占用了2个编码,其他的不精准情况是不是也要占用多个编码啊?(比如: 0.2 + 0.4 = 0.6000000000000001 等等)这种情况很常见,都这么干, IEEE754浮点编码一共才拥有 18437736874454810627(即,264 - 253 + 3)个值,将会有多少无效的编码掺杂其中。

最后,如果有个JS开发人员就想存 0.30000000000000004 这个值,为啥不让人家存啊, 0.30000000000000004 招谁惹谁了,它也是IEEE754 64位浮点编码的合法公民啊。

无论舍入界限值设置为多少,总会有这个值附近的倒霉蛋赶上。所以我现在只能使用《你不知道的JavaScript (中卷)》19页的最上面的话回复你:

看来我们能做的只有了解它,并且小心使用。

请不要以JavaScript的数值精度问题为借口来贬低这门语言,如果你这么做了,只能说明你还不懂爱情。

作为开发人员,针对小数的存储和运算问题不能怪罪IEEE754,因为误差不是IEEE754特有的,而是二进制浮点数表示方法引起的。怪罪2进制浮点数也不合适,因为计算机是2进制的。计算机也很冤枉,因为科学已经证实自然常数E(约等于2.718281828459045)进制的计算机执行效率最高,与之最近的只能是2和3,2进制计算机的物理原件相比于3进制更容易制造。即便普及的是3进制计算机,10进制小数依然无法完全转化。

如果你非要找个替罪羔羊泄愤,那只能拿锤子砸自己的手了,因为如果人类生来就只有8个手指头,习惯于使用8进制,转化成2进制小数就不会有转不尽的情况了。

以上全部,仅代表个人观点。