位置: 编程技术 - 正文

跟我学习javascript的循环(java教程)

编辑:rootadmin

推荐整理分享跟我学习javascript的循环(java教程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:java教程 视,教程java,java script课程,java script课程,java script,java script,java script,java learning,内容如对您有帮助,希望把文章链接给更多的朋友!

1、优先使用数组而不是Object类型来表示有顺序的集合

ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序。

但是在使用for..in循环对Object中的属性进行遍历的时候,确实是需要依赖于某种顺序的。正因为ECMAScript没有对这个顺序进行明确地规范,所以每个JavaScript执行引擎都能够根据自身的特点进行实现,那么在不同的执行环境中就不能保证for..in循环的行为一致性了。

比如,以下代码在调用report方法时的结果就是不确定的:

如果你确实需要保证运行的结果是建立在数据的顺序上,优先使用数组类型来表示数据,而不是直接使用Object类型。同时,也尽量避免使用for..in循环,而使用显式的for循环:

另一个特别依赖于顺序的行为是浮点数的计算:

在Item 2中,谈到了浮点数的加法操作甚至不能满足交换律: (0.1 + 0.2) + 0.3 的结果和 0.1 + (0.2 + 0.3)的结果分别是 0. 和 0.6

所以对于浮点数的算术操作,更加不能使用任意的顺序了:

当for..in的遍历顺序不一样时,最后得到的total结果也就不一样了,以下是两种计算顺序和其对应的结果:

当然,对于浮点数的计算这一类问题,有一个解决方案是使用整型数来表示,比如我们将上面的浮点数首先放大倍变成整型数据,然后计算结束之后再缩小倍:

2、绝不要向Object.prototype中添加可列举的(Enumerable)属性

如果你的代码中依赖于for..in循环来遍历Object类型中的属性的话,不要向Object.prototype中添加任何可列举的属性。

但是在对JavaScript执行环境进行增强的时候,往往都需要向Object.prototype对象添加新的属性或者方法。比如可以添加一个方法用于得到某个对象中的所有的属性名:

但是结果是下面这个样子的:

一个可行的解决方案是使用函数而不是在Object.prototype上定义新的方法:

但是如果你确实需要向Object.prototype上添加新的属性,同时也不希望该属性在for..in循环中被遍历到,那么可以利用ES5环境提供的Object.defineProject方法:

以上代码的关键部分就是将enumerable属性设置为false。这样的话,在for..in循环中就无法遍历该属性了。

3、对于数组遍历,优先使用for循环,而不是for..in循环

虽然上个Item已经说过这个问题,但是对于下面这段代码,能看出最后的平均数是多少吗?

跟我学习javascript的循环(java教程)

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

但是不要忘了在for..in循环中,被遍历的永远是key,而不是value,对于数组同样如此。因此上述for..in循环中的score并不是期望的, 等一系列值,而是0, 1等一系列索引。

所以你也许会认为最后的结果是: (0 + 1+ …+ 6) / 7 =

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

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

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

4、优先使用遍历方法而非循环

在使用循环的时候,很容易违反DRY(Don't Repeat Yourself)原则。这是因为我们通常会选择复制粘贴的方法来避免手写一段段的循环语句。但是这样做回让代码中出现大量重复代码,开发人员也在没有意义地”重复造轮子”。更重要的是,在复制粘贴的时候很容易忽视循环中的那些细节,比如起始索引值,终止判断条件等。

比如以下的for循环就存在这个问题,假设n是集合对象的长度:

可见在循环的一些细节处理上很容易出错。而利用JavaScript提供的闭包(参见Item ),可以将循环的细节给封装起来供重用。实际上,ES5就提供了一些方法来处理这一问题。其中的Array.prototype.forEach是最简单的一个。利用它,我们可以将循环这样写:

除了对集合对象进行遍历之外,另一种常见的模式是对原集合中的每个元素进行某种操作,然后得到一个新的集合,我们也可以利用forEach方法实现如下:

但是由于这种由将一个集合转换为另一个集合的模式十分常见,ES5也提供了Array.prototype.map方法用来让代码更加简单和优雅:

另外,还有一种常见模式是对集合根据某种条件进行过滤,然后得到一个原集合的子集。ES5中提供了Array.prototype.filter来实现这一模式。该方法接受一个Predicate作为参数,它是一个返回true或者false的函数:返回true意味着该元素会被保留在新的集合中;返回false则意味着该元素不会出现在新集合中。比如,我们使用以下代码来对商品的价格进行过滤,仅保留价格在[min, max]区间的商品:

当然,以上的方法是在支持ES5的环境中可用的。在其它环境中,我们有两种选择: 1. 使用第三方库,如underscore或者lodash,它们都提供了相当多的通用方法来操作对象和集合。 2. 根据需要自行定义。

比如,定义如下的方法来根据某个条件取得集合中前面的若干元素:

为了更好的重用该方法,我们可以将它定义在Array.prototype对象上,具体的影响可以参考Item 。

只有一个场合使用循环会比使用遍历函数要好:需要使用break和continue的时候。 比如,当使用forEach来实现上面的takeWhile方法时就会有问题,在不满足predicate的时候应该如何实现呢?

我们可以使用一个内部的异常来进行判断,但是它同样有些笨拙和低效:

可是使用forEach之后,代码甚至比使用它之前更加冗长。这显然是存在问题的。 对于这个问题,ES5提供了some和every方法用来处理存在提前终止的循环,它们的用法如下所示:

这两个方法都是短路方法(Short-circuiting):只要有任何一个元素在some方法的predicate中返回true,那么some就会返回;只有有任何一个元素在every方法的predicate中返回false,那么every方法也会返回false。

因此,takeWhile就可以实现如下:

实际上,这就是函数式编程的思想。在函数式编程中,你很少能够看见显式的for循环或者while循环。循环的细节都被很好地封装起来了。

5、总结

在使用for..in循环时,不要依赖于遍历的顺序。 当使用Object类型来保存数据时,需要保证其中的数据是无序的。 当需要表示带有顺序的集合时,使用数组类型而不是Object类型。 避免向Object.prototype中添加任何属性。 如果确实有必要向Object.prototype中添加方法属性,可以考虑使用独立函数替代。 使用Object.defineProperty来添加可以不被for..in循环遍历到的属性。 当遍历数组时,使用标准的for循环,而不要使用for..in循环。 在必要的场合考虑预先保存数组的长度,以提高性能。 使用遍历方法Array.prototype.forEach和Array.prototype.map来代替循环,从而让代码更加清晰可读。 对于重复出现的循环,可以考虑将它们进行抽象。通过第三方提供的方法或者自己实现。 显式的循环在一些场合下还是有用武之地的,相应的也可以使用some或者every方法。

标签: java教程

本文链接地址:https://www.jiuchutong.com/biancheng/384647.html 转载请保留说明!

上一篇:js操作table元素实现表格行列新增、删除技巧总结(js table)

下一篇:跟我学习javascript的执行上下文(java 视频教程)

  • 小规模纳税人所得税优惠政策2023
  • 企业所得税税款可以扣除吗
  • 汇款退回来的可以不做账吗
  • abc类企业是什么意思
  • 应交增值税账面和申报表不符
  • 建行网银转账复核流程
  • 一个小广告公司一年可以赚多少钱
  • 银行付款的会计怎么做账
  • 出口货物是否属于存货
  • 所得税网上申报表
  • 小规模纳税人增值税优惠政策
  • 小规模纳税人发票可以抵扣吗
  • 不能抵扣的进项税怎么做账
  • 企业接受大额捐赠,可以分次确认收入缴纳企业所得税吗?
  • 发票停票会自动恢复吗
  • 诉讼费和保全费什么时候能退还
  • 公司账户转账给个人账户有限额吗?
  • 异地预缴企业所得税会计分录
  • 高速公路通行费抵扣最新规定
  • 公司办事处人员配置标准最新
  • 医用酒精出口 需要什么条件
  • 固定资产转在建工程提折旧吗
  • 年末利润分录
  • 有什么好方法可以让小孩子少吃糖
  • linux怎么设置读写权限
  • 其他应付款不用付了怎么做分录
  • 营改增后劳务发票税率
  • 艾叶泡脚的功效与作用及禁忌
  • uniapp接入支付宝
  • 向农户收购农产品怎么打款
  • echarts css
  • php年月日时间代码
  • 资产减值对应科目
  • 票据权利期限可以缩短吗
  • vue权限管理面试题
  • 基于stm32的毕业设计
  • 什么叫相机标定
  • php简单检测网址是什么
  • 法院判决后的利息
  • 增值税会计账务处理例题
  • 职工教育经费的扣除限额
  • 专票认证是在开票软件里吗
  • 房屋出租简易计税进项税额需要转出么
  • 现金余额出现负数的原因
  • 购车买的保险分别是什么
  • 农产品加计扣除1%账务处理
  • 销售过程中发生的商业折扣计入
  • 应纳税所得额计算公式excel
  • 改良设备的入账价值
  • 如何理解其他权益工具
  • 以前年度费用科目入错 不影响以前年度利润的账务处理
  • 残疾基金缴纳标准
  • 备用金存回银行
  • 公司开办期间怎么界定
  • 资本金账户资金允许
  • 编写高质量代码改善JAVA程序的151个建议
  • mac上怎么截图
  • openbsd6.8
  • win8怎么分配磁盘空间
  • macbookpro怎么测声音
  • 强制关闭mac系统的快捷键
  • centos还原到初装
  • rds是啥
  • win7升级win8.1失败
  • 简单说明ssh远程登录流程
  • 网站备份是什么意思
  • linux常用性能监控命令
  • linux清除ssh登录记录
  • 史上最全的windows 10 激活码
  • Extjs Label的 fieldLabel和html属性值对齐的方法
  • linux怎么添加新用户
  • python中urllib.unquote乱码的原因与解决方法
  • 怎么做一个扇形图
  • 河南城乡居民医疗保险缴费怎么交
  • 什么是总分机构汇总纳税
  • 贵阳税务局领导
  • 陕西国税电子税务局app
  • 税务ukey登录界面
  • 建筑安装工程承包条例还有效吗
  • ssr服务器地址端口密码
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设