isArrayLike 检测是数组对象还是纯数组

    var property = function(key) {return function(obj) {return obj == null ? void 0 : obj[key];};};var getLength = property('length');var isArrayLike = function(collection) {var length = getLength(collection);return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;};

从下往上看  isArrayLike -> getLength -> property

property是个闭包

简化后:

getLength 返回的是一个函数

var getLength =  function(obj){return obj['length'];}

当调用

// collection = [1,2,3]

var length = getLength(collection);

    var isArrayLike = function(collection) {//  var length = [1,2,3]['length'];var length = getLength(collection);return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;};

T5.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Underscore</title>
<script src="underscore.js"></script>
</head>
<body>
</body>
</html><script type="text/javascript" src="T5.js"></script>

T5.js

_.each([1, 2, 3], alert);

执行过程

1.  接着就进入了optimizeCb函数。

  // obj = [1,2,3], iteratee = alert(), context = undefined_.each = _.forEach = function(obj, iteratee, context) {iteratee = optimizeCb(iteratee, context);var i, length;if (isArrayLike(obj)) {for (i = 0, length = obj.length; i < length; i++) {iteratee(obj[i], i, obj);}} else {var keys = _.keys(obj);for (i = 0, length = keys.length; i < length; i++) {iteratee(obj[keys[i]], keys[i], obj);}}return obj;};

2. optimizeCb 函数

  // Internal function that returns an efficient (for current engines) version// of the passed-in callback, to be repeatedly applied in other Underscore// functions.var optimizeCb = function(func, context, argCount) {if (context === void 0) return func;switch (argCount == null ? 3 : argCount) {case 1: return function(value) {return func.call(context, value);};// The 2-parameter case has been omitted only because no current consumers// made use of it.case 3: return function(value, index, collection) {return func.call(context, value, index, collection);};case 4: return function(accumulator, value, index, collection) {return func.call(context, accumulator, value, index, collection);};}return function() {return func.apply(context, arguments);};};

因为argCount = underfined。switch中的条件都不满足。

等于就直接执行了

    return function() {return func.apply(context, arguments);};

3.  isArrayLike 上面已分析过

  var isArrayLike = function(collection) {var length = getLength(collection);return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;};

返回true

4.

// 接着执行each中的if (isArrayLike(obj)) {for (i = 0, length = obj.length; i < length; i++) {iteratee(obj[i], i, obj);}}

Tips:

1.   context === void 0 判断context是否为undefined。具体解释

转载于:https://www.cnblogs.com/mafeifan/p/5498672.html

underscore.js 源码分析5 基础函数和each函数的使用相关推荐

  1. Vue.js 源码分析(九) 基础篇 生命周期详解

    先来看看官网的介绍: 主要有八个生命周期,分别是: beforeCreate.created.beforeMount.mounted.beforeupdate.updated   .beforeDes ...

  2. Vue.js 源码分析(五) 基础篇 方法 methods属性详解

    methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...

  3. underscore.js源码研究(5)

    概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...

  4. impress.js 源码分析

    impress.js 源码分析   之前做展示用幻灯片,我一直热衷于使用PPT,刚开始学习PPT时总是强行使用各种页面特效,越做越复杂.现在看来,学技术大概都要经历一个从简到繁再到简的过程吧.后来,无 ...

  5. 【FFmpeg】ffmpeg工具源码分析(一):main函数

    ffmpeg工具经常用来转换.生成媒体文件,下面是它的源码分析(一):main函数 ffmpeg版本:4.2.1 int main(int argc, char **argv) {int i, ret ...

  6. 常用JS库源码 - store.js源码/underscore.js源码

    常用JS库源码 Store.js源码 "use strict" // Module export pattern from // https://github.com/umdjs/ ...

  7. php cut截取字符串,php源码分析之DZX1.5字符串截断函数cutstr用法

    本文实例讲述了php源码分析之DZX1.5字符串截断函数cutstr用法.分享给大家供大家参考.具体分析如下: /** * 函数来源DZX1.5,文件所在 /source/function/funct ...

  8. video.js 源码分析(JavaScript)

    video.js 源码分析(JavaScript) 组织结构 继承关系 运行机制 插件的运行机制 插件的定义 插件的运行 控制条是如何运行的 UI与JavaScript对象的衔接 类的挂载方式 存储 ...

  9. Redis源码分析:基础概念介绍与启动概述

    Redis源码分析 基于Redis-5.0.4版本,进行基础的源码分析,主要就是分析一些平常使用过程中的内容.仅作为相关内容的学习记录,有关Redis源码学习阅读比较广泛的便是<Redis设计与 ...

最新文章

  1. 计算机网络和机器视觉,一文读懂计算机视觉和机器人视觉
  2. 计算机设备全年销量excel,计算机二级MS-OFFICE考试EXCEL题型汇总附答案.pdf
  3. 2020年9月编程语言排行榜:C语言继续第一,你站哪个?
  4. 利用matlab程序分别设计一正弦型信号_ARM Mbed数字信号处理
  5. FreeRTOS之Tracealyzer for FreeRTOS(FreeRTOS+Trace) 详解(源码解析+移植)
  6. 谈谈我对数据结构的理解
  7. 外卖霸王餐返利小程序开发制作功能介绍
  8. Python高级编程第2版_张亮 阿信(译)_人民邮电出版社_2017-10_v2_完整版
  9. [ISITDTU 2019]EasyPHP
  10. C51单片机数码管静态显示(附源码及工程)
  11. Reservior Sampling (蓄水池抽样算法)
  12. Android4.0上添加截屏快捷方式
  13. 【深度学习】04-01-自注意力机制(Self-attention)-李宏毅老师2122深度学习课程笔记
  14. UVa——1600(巡逻机器人)
  15. 农业无人机的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  16. No CUDA runtime is found, using CUDA_HOME=‘/usr/local/cuda:/usr/local/cuda‘
  17. Docker Swarm集群与Kubernetes的搭建与试用
  18. MySQL存emoji表情
  19. 【学点Linux】Linux该如何学习(新手入门必看)
  20. 什么是C语言数组地址

热门文章

  1. Logistic回归解析
  2. Linux环境下使用NLPIR(ICTCLAS)中文分词详解
  3. 机器学习开放数据集网站
  4. Python 二维创建与插入值的二种方法
  5. alternatives命令用法
  6. MySQL常用数据类型以及内置函数
  7. Python GUI界面编程初步 04 - Tkinter设计框架和概念
  8. 单目摄像头光学图像测距_摄像头与毫米波雷达(Radar)融合解析
  9. ios并发会造成什么问题_痔疮会造成什么伤害?
  10. php如何按日期统计,关于按日获取统计信息:按日期获取统计信息 – 日期时间列 – mysql / php...