这个世界需要一个特定的恶人,可以供人们指名道姓,千夫所指:“全都怪你”。

——村上春树《当我谈跑步时我谈些什么》

本文为读 lodash 源码的第六篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash

gitbook也会同步仓库的更新,gitbook地址:pocket-lodash

本篇分析的是 assocIndexOf 函数。

作用与用法

assocIndexOf 是 lodash 的内部函数,之前在《lodash源码分析之Hash缓存》介绍过一种这样的数据结构:

var caches = [['test1', 1],['test2',2],['test3',3]]

这是一个二维数组,每项中的第一项作为缓存对象的 key,第二项为缓存的值。

assocIndexOf 的作用是找出指定的 key 在数组中的索引值。

例如要找 keytes1 的索引 :

assocIndexOf(caches, 'test1') // 0

依赖

import eq from '../eq.js'

lodash源码分析之NaN不是NaN

源码分析

function assocIndexOf(array, key) {
let { length } = array
while (length--) {
if (eq(array[length][0], key)) {
return length
}
}
return -1
}

这段代码很精简,让 length 自减,调用 eq 函数,从二维数组的最后一项开始,逐项获取 key 值,与传入的 key 比较,遇到匹配的,马上将该项的索引返回。如果都没找到,返回 -1 。返回结果的规则与 indexOf 一致。

length--和--length

我们都知道自减还有另外一种前置的形式,即 --length,那将上面的代码改成 while(--length) 可不可以呢?试一下就知道了。

改了之后,用 caches 来测试下:

assocIndexOf(caches, 'test3') // 2
assocIndexOf(caches, 'test2') // 1
assocIndexOf(caches, 'test1') // -1

可以看到,改了之后,只影响到了第一项的结果,也就是终止条件有问题,根本没有遍历到第一项,但是后面的结果是正确的,也就说循环体里的 length 没有受到影响。

你可能会有点疑惑,while 的终止条件比较的不是 length 吗?为什么 length-- 正确,而 --length 不正确呢?

其实 while 的终止条件并不是 length ,而是 length-- 表达式所返回的结果。现在来看一下 length----length 所返回的结果有什么差别。

var length = 3
length-- // 3
length // 2

可以看到, length-- 返回的结果和自减前的一致,但是 length 已经减少 1 了。因此使用 length-- ,最后一次进入循环体应该在 length 等于 1 的时候。

再来看 --length

var length = 3
--length // 2
length // 2

--length 返回的结果跟自减后的结果一致,因此最后一次进入循环体应该是 length2 的时候,因此如果换成这种形式,会漏掉一次循环。

参考

  1. 代码之谜(二)- 语句与表达式

License

署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

作者:对角另一面

lodash源码分析之自减的两种形式的更多相关文章

  1. lodash源码分析之List缓存

    昨日我沿着河岸/漫步到/芦苇弯腰喝水的地方 顺便请烟囱/在天空为我写一封长长的信 潦是潦草了些/而我的心意/则明亮亦如你窗前的烛光/稍有暧昧之处/势所难免/因为风的缘故 --洛夫<因为风的缘故& ...

  2. lodash源码分析之baseFindIndex中的运算符优先级

    我悟出权力本来就是不讲理的--蟑螂就是海米:也悟出要造反,内心必须强大到足以承受任何后果才行. --北岛<城门开> 本文为读 lodash 源码的第十篇,后续文章会更新到这个仓库中,欢迎 ...

  3. lodash源码分析之缓存方式的选择

    每个人心里都有一团火,路过的人只看到烟. --<至爱梵高·星空之谜> 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitb ...

  4. lodash源码分析之缓存使用方式的进一步封装

    在世界上所有的民族之中,支配着他们的喜怒选择的并不是天性,而是他们的观点. --卢梭<社会与契约论> 本文为读 lodash 源码的第九篇,后续文章会更新到这个仓库中,欢迎 star:po ...

  5. lodash源码分析之数组的差集

    外部世界那些破旧与贫困的样子,可以使我内心世界得到平衡. --卡尔维诺<烟云> 本文为读 lodash 源码的第十七篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodas ...

  6. lodash源码分析之chunk的尺与刀

    以不正义开始的事情,必须用罪恶使它巩固. --莎士比亚<麦克白> 最近很多事似乎印证了这句话,一句谎言最后要用一百句谎言来圆谎. 本文为读 lodash 源码的第二篇,后续文章会更新到这个 ...

  7. lodash源码分析之compact中的遍历

    小时候, 乡愁是一枚小小的邮票, 我在这头, 母亲在那头. 长大后,乡愁是一张窄窄的船票, 我在这头, 新娘在那头. 后来啊, 乡愁是一方矮矮的坟墓, 我在外头, 母亲在里头. 而现在, 乡愁是一湾浅 ...

  8. lodash源码分析之NaN不是NaN

    暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面. --梁文道<暗恋到偷窥> 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-l ...

  9. lodash源码分析之获取数据类型

    所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! --几米 本文为读 lodash 源码的第十八篇,后续文章会更新到 ...

随机推荐

  1. node.js第二天之模块

    一.模块的定义 1.在Node.js中,以模块为单位划分所有功能,并且提供了一个完整的模块加载机制,这时的我们可以将应用程序划分为各个不同的部分. 2.狭义的说,每一个JavaScript文件都是一个 ...

  2. 【NOI2005】维护数列

    https://daniu.luogu.org/problem/show?pid=2042 一道伸展树维护数列的很悲伤的题目,共要维护两个标记和两个数列信息,为了维护MAX-SUM还要维护从左端开始的 ...

  3. 关于Switch case条件语句中无break的用法

    关于Switch case条件语句的另类用法       今天在拜读一位前辈的程序时,遇到了这样一段程序: /***************************/ switch(operation ...

  4. Okio 之初探黄龙

    Okio 是一个包装了 java.io 和 java.nio api 的库,以便可以更容易的访问.存储以及处理数据. ByteStrings 和 Buffers Okio 是围绕着两个容器类构建起来的 ...

  5. 鼠标悬停,图片放大 CSS实现

    因为最近做的项目刚好用到了这个实现,分享出来   class=enlarge 为div标签的class div img 为标签 .enlarge div img:hover{ transform: s ...

  6. mongoDB之集合操作

    mongoDB之集合操作 mongoDB中的集合相当于mysql中的表. mongoDB中集合的创建: 第一种方式:不限制集合大小   db.createCollection("集合名称&q ...

  7. canvas雪花

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 在Intellij里使用Erlang依赖库

    这里以protobuffs为例,记录一下环境的配置,发现这种东西中文的资料真的不多,无论是分享还是记录都是很好的 1.创建一个文件夹名use_proto, 配置rebar.config文件如下: {d ...

  9. 五.RabbitMQ之路由(Routing)和主题(topics)

    翻译官网的文章已经翻译了几天了,这份官方文档写的总体算是很简洁易懂.它让我们很快的入门并了解了RabbitMQ的运作原理和使用方式.本篇最后介绍一下Exchange的另外两种类别,即direct和to ...

  10. 关于在Windows下Composer下载安装Yii2.0

    先是composer的安装,主要有两个方式,一个直接下载安装包安装,Composer-steup.exe文件,第二种直接下载composer.phar文件,用php去运行这个文件可以一样起到作用,之后 ...