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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值