本系列作为Effective JavaScript的读书笔记。

对于以下这段代码,能看出最后的平均数是多少吗?

var scores = [98, 74, 85, 77, 93, 100, 89];
var total = 0;
for (var score in scores) {
total += score;
}
var mean = total / scores.length;
mean; // ?

通过计算,最后的结果应该是88。

可是不要忘了在for..in循环中,被遍历的永远是key。而不是value,对于数组相同如此。

因此上述for..in循环中的score并非期望的98。
74等一系列值,而是0, 1等一系列索引。

所以你或许会觉得最后的结果是:

(0 + 1+
…+ 6) / 7 = 21

可是这个答案也是错的。另外一个关键点在于,for..in循环中key的类型永远都是字符串类型,因此这里的+操作符运行的实际上是字符串的拼接操作:

最后得到的total实际上是字符串00123456。

这个字符串转换成数值类型后的值是123456。然后再将它除以元素的个数7,就得到了最后的结果:17636.571428571428

所以,对于数组遍历,还是使用标准的for循环最好:

var scores = [98, 74, 85, 77, 93, 100, 89];
var total = 0;
for (var i = 0, n = scores.length; i < n; i++) {
total += scores[i];
}
var mean = total / scores.length;
mean; // 88

毕竟对于这样的for循环。开发者是再熟悉只是了。绝对不会将索引变量i当做是值。而且标准的for循环也可以保证循环的顺序。保证这一点对于浮点数的算术操作十分重要。

在以上的代码中。也运用到了一个小优化。

就是在循环開始前计算好了数组的长度作为循环边界。当在for循环中不会对数组本身进行加入/删除元素操作时,可以略微提升一点性能。这样就不会在每次循环都对集合的长度进行查询了。

总结:

  1. 当遍历数组时,使用标准的for循环,而不要使用for..in循环。
  2. 在必要的场合考虑预先保存数组的长度,以提高性能。

Effective JavaScript Item 49 对于数组遍历,优先使用for循环,而不是for..in循环的更多相关文章

  1. [Effective JavaScript 笔记]第49条:数组迭代要优先使用for循环而不是for...in循环

    示例 下面代码中mean的输出值是多少? var scores=[98,74,85,77,93,100,89]; var total=0; for(var score in scores){ tota ...

  2. Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合

    本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ...

  3. Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__

    本系列作为Effective JavaScript的读书笔记. 在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API.可是在非常多运行环境中.也提供了一个特殊的_ ...

  4. Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表

    本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...

  5. Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数

    本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ...

  6. Effective JavaScript Item 40 避免继承标准类型

    本系列作为Effective JavaScript的读书笔记. ECMAScript标准库不大.可是提供了一些重要的类型如Array,Function和Date.在一些场合下.你或许会考虑继承当中的某 ...

  7. Effective JavaScript Item 37 认识this的隐式指向

    本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...

  8. Effective JavaScript Item 10 避免使用with

    本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ...

  9. Effective JavaScript Item 39 绝不要重用父类型中的属性名

    本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ...

随机推荐

  1. ASP.NET-internat身份验证

    ASP.NET-internat身份验证默认在webconfig中配置的代码是这样的 <system.web> <compilation debug="true" ...

  2. Android自己定义百度地图缩放图标

    自己定义实现Android百度地图的缩放图标,须要自己定义一个缩放控件,实现效果例如以下: 这里的缩放效果,实现了点击button能够对地图的放大缩小,通过手势放大与缩小也控制缩放图标的可用状态.详细 ...

  3. 搜狗面试的经典题(C++map按值排序,class struct的差别)

    一:起因 (1)java  Map排序(key,value).请看还有一篇博客 java Map排序 (2)c++ map排序(key,value),能够对c++ map和java Map进行对照:之 ...

  4. Spark技术在京东智能供应链预测的应用——按照业务进行划分,然后利用scikit learn进行单机训练并预测

    3.3 Spark在预测核心层的应用 我们使用Spark SQL和Spark RDD相结合的方式来编写程序,对于一般的数据处理,我们使用Spark的方式与其他无异,但是对于模型训练.预测这些需要调用算 ...

  5. 解决linux ping: unknown host www.baidu.com

    如果ping域名的时候出现ping:unknown host  xxx.xxx 但是ping IP地址的时候可以通的话 可知是dns服务器没有配置好, 查看一下配置文件/etc/resolv.conf ...

  6. 配置NTP集群时间同步(二)

    [root@hadoop1 bin]# rpm -qa|grep ntp 没有的话用yum -y install ntp安装(要记着每台机器上都要安装) [root@hadoop1 bin]# vi ...

  7. Windbg调试托管代码

    Windbg调试.net托管代码需要借助于SOS.dll,.Net 4.0的32位sos.dll的路径在C:\Windows\Microsoft.NET\Framework\v4.0.30319,64 ...

  8. Activiti BPMN 2.0 designer eclipse插件安装

    官方网是这样说的: https://www.activiti.org/userguide/index.html#springSpringBoot The following installation ...

  9. MySQL存储过程和自定义函数、Navicat for mysql、创建存储过程和函数、调用存储过程和函数的区别

    1 MySQL存储过程和函数 过程和函数,它们被编译后保存在数据库中,称为持久性存储模块(Persistent Stored Module,PSM),可以反复调用,运行速度快. 1.1 存储过程 存储 ...

  10. php--tp5在查询到的数据中添加新字段