zoukankan      html  css  js  c++  java
  • 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。具体解释

    
    
  • 相关阅读:
    普元EOS中nui(对jquery MiniUi的封装)合并表头
    css--让箭头动起来
    在开发中说一说你最讨厌什么函数????
    前端开发学习路线
    默哀日,网页置灰,开发人员你应该掌握的
    window--环境下升级node的版本(因为低版本node运行Vue项目有问题)
    小程序--模板<template>的定义和使用
    小程序--app.js之App方法
    小程序---页面配置文件,只对自己的页面有效果
    javascript 内存模型
  • 原文地址:https://www.cnblogs.com/mafeifan/p/5498672.html
Copyright © 2011-2022 走看看