Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
本系列作为Effective JavaScript的读书笔记。
ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序。
可是在使用for..in循环对Object中的属性进行遍历的时候,确实是须要依赖于某种顺序的。
正由于ECMAScript没有对这个顺序进行明白地规范,所以每一个JavaScript运行引擎都可以依据自身的特点进行实现。那么在不同的运行环境中就不能保证for..in循环的行为一致性了。
比方,下面代码在调用report方法时的结果就是不确定的:
function report(highScores) {
var result = "";
var i = 1;
for (var name in highScores) { // unpredictable order
result += i + ". " + name + ": " +
highScores[name] + "\n";
i++;
}
return result;
}
report([{ name: "Hank", points: 1110100 },
{ name: "Steve", points: 1064500 },
{ name: "Billy", points: 1050200 }]);
// ?
假设你确实须要保证执行的结果是建立在数据的顺序上,优先使用数组类型来表示数据,而不是直接使用Object类型。同一时候。也尽量避免使用for..in循环,而使用显式的for循环:
function report(highScores) {
var result = "";
for (var i = 0, n = highScores.length; i < n; i++) {
var score = highScores[i];
result += (i + 1) + ". " +
score.name + ": " + score.points + "\n";
}
return result;
}
report([{ name: "Hank", points: 1110100 },
{ name: "Steve", points: 1064500 },
{ name: "Billy", points: 1050200 }]);
// "1. Hank: 1110100\n2. Steve: 1064500\n3. Billy: 1050200\n"
还有一个特别依赖于顺序的行为是浮点数的计算:
var ratings = {
"Good Will Hunting": 0.8,
"Mystic River": 0.7,
"21": 0.6,
"Doubt": 0.9
};
在Item 2中。谈到了浮点数的加法操作甚至不能满足交换律:
(0.1 + 0.2) + 0.3
的结果和 0.1 + (0.2 + 0.3)的结果各自是
0.600000000000001
和 0.6
所以对于浮点数的算术操作,更加不能使用随意的顺序了:
var total = 0, count = 0;
for (var key in ratings) { // unpredictable order
total += ratings[key];
count++;
}
total /= count;
total; // ?
当for..in的遍历顺序不一样时,最后得到的total结果也就不一样了。下面是两种计算顺序和其相应的结果:
(0.8 + 0.7 + 0.6 +0.9) / 4 // 0.75
(0.6 + 0.8 + 0.7 +0.9) / 4 // 0.7499999999999999
当然,对于浮点数的计算这一类问题,有一个解决方式是使用整型数来表示,比方我们将上面的浮点数首先放大10倍变成整型数据。然后计算结束之后再缩小10倍:
(8+ 7 + 6 + 9) / 4 / 10
// 0.75
(6+ 8 + 7 + 9) / 4 / 10
// 0.75
总结:
- 在使用for..in循环时。不要依赖于遍历的顺序。
- 当使用Object类型来保存数据时,须要保证当中的数据是无序的。
- 当须要表示带有顺序的集合时。使用数组类型而不是Object类型。
Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合的更多相关文章
- Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__
本系列作为Effective JavaScript的读书笔记. 在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API.可是在非常多运行环境中.也提供了一个特殊的_ ...
- Effective JavaScript Item 51 在类数组对象上重用数组方法
Array.prototype对象上的标准方法被设计为也能够在其他对象上重用 - 即使不是继承自Array的对象. 因此,在JavaScript中存折一些类数组对象(Array-like Object ...
- Effective JavaScript Item 49 对于数组遍历,优先使用for循环,而不是for..in循环
本系列作为Effective JavaScript的读书笔记. 对于以下这段代码,能看出最后的平均数是多少吗? var scores = [98, 74, 85, 77, 93, 100, 89]; ...
- Effective JavaScript Item 40 避免继承标准类型
本系列作为Effective JavaScript的读书笔记. ECMAScript标准库不大.可是提供了一些重要的类型如Array,Function和Date.在一些场合下.你或许会考虑继承当中的某 ...
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...
- Effective JavaScript Item 10 避免使用with
本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ...
- Effective JavaScript Item 39 绝不要重用父类型中的属性名
本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ...
- Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数
本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ...
- Effective JavaScript Item 37 认识this的隐式指向
本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...
随机推荐
- SqlServer日常积累(一)
1. 将一个表的数据插入另一个表 情况一:目标表已存在 (1)如果2张表的字段一致,并且希望插入全部数据,可以用这种方法: Insert Into 目标表 Select * From 来源表; --例 ...
- 虎嗅: 小米盒子vs乐视盒子
机顶盒并非新鲜概念,可一旦和互联网发生了跨界关系,就会产生奇妙的反应.自年初小米盒子和乐视盒子分别在突破重重阻碍成功发售之后,互联网企业进军硬件制造领域的趋势愈发明显.今天我们拿到了两家的盒子产品,从 ...
- UVA 10026 Shoemaker's Problem 鞋匠的难题 贪心+排序
题意:鞋匠一口气接到了不少生意,但是做鞋需要时间,鞋匠只能一双一双地做,根据协议每笔生意如果拖延了要罚钱. 给出每笔生意需要的天数和每天的罚钱数,求出最小罚钱的排列顺序. 只要按罚款/天数去从大到小排 ...
- tomcat之组成结构
1 - Tomcat Server的组成部分 1.1 - Server A Server element represents the entire Catalina servlet containe ...
- Jacoco覆盖率工具使用
Jacoco介绍 Jacoco是一个开源的覆盖率工具.Jacoco可以嵌入到Ant .Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序.很多第 ...
- vue 源码 断点调试
1.添加sourceMap sourceMap: true 2.npm run dev 会生成vue.js.map 3.断点调试 <!DOCTYPE html> <html> ...
- Openerp对日期时间的操作
日期格式化字符串:DATE_FORMAT = "%Y-%m-%d" 日期时间格式字符串:DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" ...
- SQL Server 2012 “阻止保存要求又一次创建表”的更改问题的设置方法
我们在用SQL Server 2012 建完表后,插入或改动随意列时,提示:当用户在在SQL Server 2012企业管理器中更改表结构时.必需要先删除原来的表.然后又一次创建新表,才干完毕表的更改 ...
- 【#254_DIV2】-A B C
题目链接:http://codeforces.com/contest/445 解题报告: 俄国人今天不知道为什么九点钟就比赛了.仅仅过了两道题,第三题全然没思路,有时间单独去刷第三题吧,看起来非常难 ...
- Android 华为U8818真机调试 无法打印Logcat
摘抄至:http://blog.csdn.net/studyalllife/article/details/8558258 在我们使用真机进行Android应用调试时,无法获得调试信息,错误提演示样例 ...