underscore方法使用_underscore 如何使用-程序员宅基地

技术标签: underscore  前端  javascript  

underscore中template的用法

可以传对象 data 作为第二个参数给模板 template 来直接呈现, 这样页面会立即呈现而不是返回一个模板函数.

var T = $('#T').html();
b.html(_.template(T, res.result))

当要给模板函数赋值的时候,可以传递一个含有与模板对应属性的data对象 。

template: {
    relation: _.template($('#JT_Relation').html())
}
this.template.relation({
    relations : res.userRelation})

underscore中判断变量相等源码

  var ObjProto = Object.prototype;
  var nativeKeys = Object.keys;
  var hasEnumBug = !{toString:null}.propertyIsEnumerable('toString');

  //判断类数组
  var isArrayLike = function(collection) {
    
      var length = getLength(collection);
      return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
  };

  //判断函数
  _.isFunction = function(obj) {
    
      return typeof obj == 'function' || false;
  };

  // 判断对象
  _.isObject = function(obj) {
    
      var type = typeof obj;
      return type === 'function' || type === 'object' && !!obj;
  };

  //返回一个包装后的对象
  var _ = function(obj) {
    
      if (obj instanceof _) return obj;
      if (!(this instanceof _)) return new _(obj);
      this._wrapped = obj;
  };

这里放一个this相关的点

var a= {
   value:"随意"}
undefined
  var t = function(obj) {
      if (obj instanceof t) {
          console.log("obj instanceof t",this);
      }
      if (!(this instanceof t)) {
          console.log("!(this instanceof t)", this);
      }
      this._wrapped = obj;
      console.log("wrapped", this);
  };

输出的结果是

->t(a)
!(this instanceof t) Window {
   stop: function, open: function, alert: function, confirm: function, prompt: function…}
wrapped t {
   _wrapped: Object}

重回主干,继续看判断变量相等用到的方法

  // Shortcut function for checking if an object has a given property directly
  // on itself (in other words, not on a prototype).
  _.has = function(obj, key) {
      return obj != null && hasOwnProperty.call(obj, key);
  };
  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);

为什么不直接使用原生的indexOf呢?createIndexFinder这一层做了什么?一起带着问题往下看


  // Generator function to create the indexOf and lastIndexOf functions
  function createIndexFinder(dir, predicateFind, sortedIndex) {
    
      return function(array, item, idx) {
    
          var i = 0,
              length = getLength(array);
          if (typeof idx == 'number') {
              if (dir > 0) {
                  i = idx >= 0 ? idx : Math.max(idx + length, i);
              } else {
                  length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
              }
          } else if (sortedIndex && idx && length) {
              idx = sortedIndex(array, item);
              return array[idx] === item ? idx : -1;
          }
          if (item !== item) {
              idx = predicateFind(slice.call(array, i, length), _.isNaN);
              return idx >= 0 ? idx + i : -1;
          }
          for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
              if (array[idx] === item) return idx;
          }
          return -1;
      };
  }

可以看到通过createIndexFinder的包装,是的indexOf兼容了,封装后调用更加方便。



  // Retrieve the names of an object's own properties.
  // Delegates to **ECMAScript 5**'s native `Object.keys`
  _.keys = function(obj) {
     
      if (!_.isObject(obj)) return [];
      if (nativeKeys) return nativeKeys(obj);
      var keys = [];
      for (var key in obj)
          if (_.has(obj, key)) keys.push(key);
          // Ahem, IE < 9.
      if (hasEnumBug) collectNonEnumProps(obj, keys);
      return keys;
  };

    // Retrieve the values of an object's properties.
  _.values = function(obj) {
     
      var keys = _.keys(obj);
      var length = keys.length;
      var values = Array(length);
      for (var i = 0; i < length; i++) {
          values[i] = obj[keys[i]];
      }
      return values;
  };

  // Determine if the array or object contains a given item (using `===`).
  // Aliased as `includes` and `include`.
  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
     
      if (!isArrayLike(obj)) obj = _.values(obj);
      if (typeof fromIndex != 'number' || guard) fromIndex = 0;
      return _.indexOf(obj, item, fromIndex) >= 0;
  };


function collectNonEnumProps(obj, keys) {
     
     var nonEnumIdx = nonEnumerableProps.length;
     var constructor = obj.constructor;
     var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;

     // Constructor is a special case.
     var prop = 'constructor';
     if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);

     while (nonEnumIdx--) {
         prop = nonEnumerableProps[nonEnumIdx];
         if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
             keys.push(prop);
         }
     }
 }



  // Internal recursive comparison function for `isEqual`.
  var eq = function(a, b, aStack, bStack) {
     
      // Identical objects are equal. `0 === -0`, but they aren't identical.
      // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
      if (a === b) return a !== 0 || 1 / a === 1 / b;
      // A strict comparison is necessary because `null == undefined`.
      if (a == null || b == null) return a === b;
      // Unwrap any wrapped objects.
      if (a instanceof _) a = a._wrapped;
      if (b instanceof _) b = b._wrapped;
      // Compare `[[Class]]` names.
      var className = toString.call(a);
      if (className !== toString.call(b)) return false;
      switch (className) {
          // Strings, numbers, regular expressions, dates, and booleans are compared by value.
          case '[object RegExp]':
              // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
          case '[object String]':
              // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
              // equivalent to `new String("5")`.
              return '' + a === '' + b;
          case '[object Number]':
              // `NaN`s are equivalent, but non-reflexive.
              // Object(NaN) is equivalent to NaN
              if (+a !== +a) return +b !== +b;
              // An `egal` comparison is performed for other numeric values.
              return +a === 0 ? 1 / +a === 1 / b : +a === +b;
          case '[object Date]':
          case '[object Boolean]':
              // Coerce dates and booleans to numeric primitive values. Dates are compared by their
              // millisecond representations. Note that invalid dates with millisecond representations
              // of `NaN` are not equivalent.
              return +a === +b;
      }

      var areArrays = className === '[object Array]';
      if (!areArrays) {
          if (typeof a != 'object' || typeof b != 'object') return false;

          // Objects with different constructors are not equivalent, but `Object`s or `Array`s
          // from different frames are.
          var aCtor = a.constructor,
              bCtor = b.constructor;
          if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
                  _.isFunction(bCtor) && bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)) {
              return false;
          }
      }
      // Assume equality for cyclic structures. The algorithm for detecting cyclic
      // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.

      // Initializing stack of traversed objects.
      // It's done here since we only need them for objects and arrays comparison.
      aStack = aStack || [];
      bStack = bStack || [];
      var length = aStack.length;
      while (length--) {
          // Linear search. Performance is inversely proportional to the number of
          // unique nested structures.
          if (aStack[length] === a) return bStack[length] === b;
      }

      // Add the first object to the stack of traversed objects.
      aStack.push(a);
      bStack.push(b);

      // Recursively compare objects and arrays.
      if (areArrays) {
          // Compare array lengths to determine if a deep comparison is necessary.
          length = a.length;
          if (length !== b.length) return false;
          // Deep compare the contents, ignoring non-numeric properties.
          while (length--) {
              if (!eq(a[length], b[length], aStack, bStack)) return false;
          }
      } else {
          // Deep compare objects.
          var keys = _.keys(a),
              key;
          length = keys.length;
          // Ensure that both objects contain the same number of properties before comparing deep equality.
          if (_.keys(b).length !== length) return false;
          while (length--) {
              // Deep compare each member
              key = keys[length];
              if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
          }
      }
      // Remove the first object from the stack of traversed objects.
      aStack.pop();
      bStack.pop();
      return true;
  };

  // Perform a deep comparison to check if two objects are equal.
  export function isEqual(a, b) {
     
      return eq(a, b);
  };
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wangning_elsa/article/details/54985107

智能推荐

matlab 高斯一阶导,高斯函数及其各阶导数-程序员宅基地

文章浏览阅读1.6k次。[使用Matlab进行拟合是图像处理中线条变换的一个重点内容,本文将详解Matlab中的直线拟合和曲线拟合用法。关键函数:fittypeFit type for curve and surface fittingSyntax在图像处理中经常要用到高斯函数,高斯滤波是典型的低通滤波,对图像有平滑作用。高斯函数的一阶、二阶导数也可以进行高通滤波,比如canny算子中用到的是高斯函数的一阶导数,LOG算..._matlab仿真高斯函数导数

vue 普通列表间隔无限滚动_vue实现表格单行有间隔的平滑滚动播放效果-程序员宅基地

文章浏览阅读512次。vue 普通列表间隔滚动实现原理:表格上滑一行数据的高度,如何将第一行数据删除放入到数组尾部,实现循环滚动效果。利用 setInterval 控制滚动的间隔时间。(记得离开页面时一定要销毁 setInterval)transition 里设置的时间要和setTimeout里的相同, 避免滑动过程中数据删除出现错误。滚动过程中每行的背景颜色会随着滚动变化,在数组中加入固定的 key(可随意命名) 字段,实现间隔行颜色不相同(index不能使用,会随滚动变化)。@mouseover 鼠标移入,@mo_vue实现表格单行有间隔的平滑滚动播放效果

darknet测试yolo_darknet 测试-程序员宅基地

文章浏览阅读318次。YOLO: Real-Time Object Detection_darknet 测试

有了市场,自研操作系统才会被真正的用起来_系统真正用起来-程序员宅基地

文章浏览阅读964次。10月23-25日,“长沙 · 中国 1024 程序员节”盛大举行,以开源为主议题,聚焦开源技术及生态建设、操作系统及硬件创新、开源社区及商业化发展等多个重要话题。大会吸引到上千名开发者现场参加,500万+程序员线上线下关注互动。齐聚岳麓,共话开源未来中国工程院院士倪光南,中国第一代程序员、“WPS之父”求伯君,西安邮电大学教授陈莉君,deepin创始人、统信软件总经理刘闻欢,华为openEuler负责人江大勇,阿里操作系统团队负责人马涛,SylixOS嵌入式操作系统创始人韩辉,RT-Thread创始._系统真正用起来

哲学家不会吃饭了,我们快来帮帮他们(C语言、进程通信)_哲学家进餐问题c语言实现-程序员宅基地

文章浏览阅读272次。哲学家不会吃饭了,我们快来帮帮他们皮老师课堂开课啦皮老师:同学们,今天我们来讨论讨论哲学家吃饭问题,哲学家吃法问题是由大名鼎鼎的Dijkstra提出的,大家看黑板,看看什么是哲学家吃饭问题。每个哲学家面前一碗面条子,每碗面间有一根筷子哲学家就会干两件事,吃饭、思考哲学家吃饭的时候要依次把左右两侧的筷子拿起来(不分次序)才能吃面吃完了把筷子放回去继续思考皮老师:如何才能不发生死锁呢?张三同学抢答:拿不到筷子就等着呗,等别旁边的吃完了不就拿到了么?皮老师:假如五个人都同_哲学家进餐问题c语言实现

Android Studio编译错误:Suggestion: use tools:overrideLibrary="xxx.xxx.xxx" to force usage_androidstudio suggestions-程序员宅基地

文章浏览阅读6.3k次。Suggestion: use tools:overrideLibrary="xxx.xxx.xxx" to force usage_androidstudio suggestions

随便推点

WinCE下串口蓝牙模块的调试-程序员宅基地

文章浏览阅读144次。 拿到模块后,先请ZWEI帮忙把模块飞到板子上,最后的情形有点像蜈蚣跟蜘蛛在打仗,而且难分难解。 飞完线后用串口调试助手发送AT#指令,以确认蓝牙模块和串口都能正常工作。结果,运气不太好,发出去的指令就好像石沉大海了一样。 又请ZWEI用示波器量了一下RXD和TXD,信号都正常。把TXD和RXD短接,用串口调试助手自发自收,也不成功。串口调试助手,应该是没问题的,久经考验..._wince车载dvd用着用着会自己切换音源

sparkSQL sparkSQL整合hive(spark on hive)-程序员宅基地

文章浏览阅读851次,点赞2次,收藏4次。sparkSQL整合hivesparkSQL整合hivesparkSQL整合hive步骤示例数据库保存在本地和数据库保存在HDFS应用场景sparkSQL整合hivesparkSQL整合hive,即spark on hive。本质是把hive当做数据源,使用spark作为计算引擎来处理数据。sparkSQL整合hive步骤把hive安装目录下conf文件夹里的hive-site.xml拷贝到集群每一个spark安装目录下对应的conf文件夹中目的:让spark知道存放hive表的元数据的M

爬虫 自动化工具-mongo-多线程爬虫_broeser-程序员宅基地

文章浏览阅读347次。一、selenium框架1、selenium介绍# 介绍: 1.selenium是一个web自动化测试用的框架. 程序员可以通过代码实现对浏览器的控制, 比如打开网页, 点 击网页中的元素, 实现鼠标滚动等操作. 2.它支持多款浏览器, 如谷歌浏览器, 火狐浏览器等等, 当然也支持无头浏览器. # 目的: 在爬取数据的过程中, 经常遇到动态数据加载, 一般动态数据加载有两种, 一种..._broeser

如何更改nrf51822的主服务uuid与特性的uuid不一样_nrf52840 服务 读 写uuid计数不一致-程序员宅基地

文章浏览阅读775次。最近有一个CSDN的好友给我留言,询问如何设置主服务uuid和特性uuid不一样,如下图:我以为这个问题很简单,网上应该一大堆,但是搜索一下,却发现没有这样的文章,于是,把自己的代码给分享出来,供大家学习。废话就少说,这里直接把代码复制下来。大家可以通过对比软件对比一下就行。使用的是SDK11的,串口服务ble_char,uint32_t ble_char_init(ble_char_t * p_char, const ble_char_init_t * p_char_init){ uin_nrf52840 服务 读 写uuid计数不一致

第十五届蓝桥杯嵌入式省赛真题题目和答案-程序员宅基地

文章浏览阅读242次。该题目是本人考完之后写的第十五届蓝桥杯嵌入式省赛真题题目和答案,有些答案也不完全确定,仅供参考,

子类继承父类重写父类的属性值问题_c# 子类修改父类的属性值为什么父类属性值没变-程序员宅基地

文章浏览阅读2.6k次,点赞2次,收藏8次。案例一试想一下代码的执行结果package com.syc.test;public class A { public static void main(String[] args) { FatherClass father = new FatherClass(); System.out.println(father.info); SonClass son = new ..._c# 子类修改父类的属性值为什么父类属性值没变

推荐文章

热门文章

相关标签