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

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

本文为读 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. Swagger服务API治理详解

    swager2的简介 在App后端开发中经常需要对移动客户端(Android.iOS)提供RESTful API接口,在后期版本快速迭代的过程中,修改接口实现的时候都必须同步修改接口文档,而文档与代码 ...

  2. 深度解剖sesssion运行原理

    已经大半年没有更新博客了,一方面有比博客更重要的事情要做,另外一方面也没有时间来整理知识,所以希望在接下来的日子里面能够多多的写博客来与大家交流 什么是session session的官方定义是:Se ...

  3. 【前端】Util.js-ES6实现的常用100多个javaScript简短函数封装合集(持续更新中)

    Util.js (持续更新中...) 项目地址: https://github.com/dragonir/Util.js 项目描述 Util.js 是对常用函数的封装,方便在实际项目中使用,主要内容包 ...

  4. Python爬虫:用BeautifulSoup进行NBA数据爬取

    爬虫主要就是要过滤掉网页中没用的信息.抓取网页中实用的信息 一般的爬虫架构为: 在python爬虫之前先要对网页的结构知识有一定的了解.如网页的标签,网页的语言等知识,推荐去W3School: W3s ...

  5. 【hdu5419】Victor and Toys

    求求求 搞搞搞 搞法例如以下:考虑每一个数w[i]w[i]对答案的贡献,呃. . .首先答案一定是 ∑[...](m3) \sum [...]\over {m\choose 3}的形式,仅仅须要搞分子 ...

  6. 我的Java开发学习之旅------&gt;Base64的编码思想以及Java实现

    Base64是一种用64个字符来表示随意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,由于二进制文件包括非常多无法显示和打印的字符.所以,假设要让记事本这种 ...

  7. flask框架-decorator装饰器

    调用包: from functools import wraps 装饰器其实就是一个函数:参数是一个函数,返回值是一个函数 1.装饰器使用是通过@符号,在函数的上面 2.装饰器中定义的函数,要使用*a ...

  8. F01:金融学第一定律:时间的价值

    很小的时候,我们就听大人们讲过:时间就是金钱. 长大了,也觉得这句话应该是对的.我们很珍惜时间,但是似乎没有看到金钱的急剧增加啊.总之,这是模糊,体验感又不强的一句话. 既然谈到时间的价值,价值最容易 ...

  9. 【quickhybrid】架构一个Hybrid框架

    前言 虽然说本系列中架构篇是第一章,但实际过程中是在慢慢演化的第二版中才有这个概念, 经过不断的迭代,演化才逐步稳定 明确目标 首先明确需要做成一个什么样的框架? 大致就是: 一套API规范(统一An ...

  10. python自动化--字符串和整数的转换,while的循环体

    字符串(str)和整数(int)类型变量的结合 *遵循只有同一类型的变量才可以结合. *不同类型的变量之间的转换 实例:实现打印出"192.168.100"和1的结合出" ...