防冲突

underscore 使用 _ 作为函数的挂载对象,如果页面中已经存在了 _ 对象,underscore 就会覆盖该对象,举个例子:

var _ = {value: 1 }// 引入 underscore 后
console.log(_.value); // undefined
复制代码

所以 underscore 提供了 noConflict 功能,可以放弃 underscore 的控制变量 _,返回 underscore 对象的引用。

var _ = {value: 1 }// 引入 underscore 后// 放弃 "_",使用 "$"
var $ = _.noConflict();console.log(_.value); // 1// 使用 underscore 的方法
$.each([1, 2, 3], alert);
复制代码

那么 noConflict 函数是如何实现的呢?

首先,在 underscore 执行的时候,会储存之前的 _ 对象,然后当执行 noConflict 函数的时候,再将之前储存的 _ 对象赋给全局对象,最后返回 underscore 对象。这样,我们就可以利用返回的 underscore 对象使用 underscore 提供的各种方法。

// 源码一开始的时候便储存之前的 _ 对象
var previousUnderscore = root._;_.noConflict = function() {root._ = previousUnderscore;return this;
};
复制代码

是的,就是这么简单。你可以轻松为你的函数库添加防冲突功能。

接下来我们看 underscore 中的一些功能函数。

_.identity

_.identity = function(value) {return value;
};
复制代码

看起来匪夷所思的一个函数,传入一个值,然后返回该值,为什么不直接使用该值呢?

还记得我们在《underscore 系列之内部函数 cb 和 optimizeCb》中接触过这个函数吗?

如果我们自己编写了一个 _.map 函数:

_.map = function(arr, iteratee){return arr.map(iteratee)
}
复制代码

然而当我们这样使用 _.map([1, 2, 3]) 时便会报错,因为我们没有传入 iteratee 函数,然而使用 underscore 却没有问题,结果是返回一个相同的新数组,原因就在于当 iteratee 为 undefined 的时候,underscore 视为传入了 _.identity 函数。就相当于:

_.map = function(arr, iteratee){if (!iteratee) iteratee = _.identityreturn arr.map(iteratee)
}
复制代码

简而言之,如果我们想要复制一个数组:

var clonedArr = [1, 2, 3].map(_.identity) // [1, 2, 3]
复制代码

_.constant

_.constant = function(value) {return function() {return value;};
};
复制代码

该函数传入一个 value,然后返回一个返回该 value 的函数,这又有什么用呢?我们来看个 demo:

var value = 1;
var getValue = _.constant(value);value = 2;getValue(); // 1
getValue(); // 1
复制代码

这很容易让人想到 ES6 的 const,我一开始以为就是用来表示 ES6 的 const ,后来看了这个函数起源的 issue,才发现并非如此,它其实像下面的 _.noop 函数一样可以作为默认函数使用。

举个例子:

_.select(collection, filterFunction || function() { return true; })
复制代码

我们根据 filterFunction 筛选 collection 中符合条件的元素,如果没有传 filterFunction,我们就返回所有的元素,如果有 _.constant 函数,我们可以将其简化为:

_.select(collection, filterFunction || _.constant(true))
复制代码

尽管没有什么大的改变,但是语义更加明确。

_.noop

_.noop = function(){};
复制代码

一个空函数,看起来依旧没什么用……

noop 函数可以用于作为默认值,这样就可以省去是否存在的判断,举个例子:

// 不使用 noop
function a(value, callback){// 每次使用 callback 都要判断一次_.isFunction(callback) && callback()
}// 使用 noop
function a(value, callback) {// 判断一次if(!_.isFunction(callback)) callback = _.noop;// 以后都可以直接使用callback()
}
复制代码

deepGet

var deepGet = function(obj, path) {var length = path.length;for (var i = 0; i < length; i++) {if (obj == null) return void 0;obj = obj[path[i]];}return length ? obj : void 0;
};
复制代码

deepGet 用于获得对象深层次的值。举个例子:

var obj = { value: { deepValue: 2}
}console.log(deepGet(obj, ['value', 'deepValue']))
复制代码

使用这个函数,可以避免深层次取值时,因为没有其中的一个属性,导致的报错。

shallowProperty

var shallowProperty = function(key) {return function(obj) {return obj == null ? void 0 : obj[key];};
};
复制代码

shallowProperty 也是用于获取对象的属性,也许你会好奇在开发中,直接使用. 不就可以获取对象的属性了,为什么还要写成这样呢?我们来举个例子:

// 获取 arr 所有元素的 name 属性
var arr = [{value: 1,name: 'Kevin'},{value: 2,name: 'Daisy'}
]// 普通方式
var names = arr.map(function(item){return item.name;
})// 使用 shallowProperty
var names = arr.map(shallowProperty('name'))
复制代码

_.property

_.property = function(path) {if (!_.isArray(path)) {return shallowProperty(path);}return function(obj) {return deepGet(obj, path);};
};
复制代码

_.property 结合了 deepGet 和 shallowProperty,可以获取元素深层次的值。上面一个例子也可以写成:

var names = arr.map(_.property('name'))
复制代码

_.propertyOf

_.propertyOf = function(obj) {if (obj == null) {return function(){};}return function(path) {return !Array.isArray(path) ? obj[path] : deepGet(obj, path);};
};
复制代码

_.property 返回一个函数,这个函数返回任何传入的对象的指定属性。

_.propertyOf_.property 相反。需要一个对象,并返回一个函数,这个函数将返回一个提供的属性的值。

我们写个例子:

// 获取 person 对象的所有属性值
var person = {name: 'Kevin',age: '18'
};// 普通方式
var values = Object.keys(person).map((key) => person[key]); // ["Kevin", "18"]// 使用 _.propertyOf
var values = Object.keys(person).map(_.propertyOf(person)); // ["Kevin", "18"
复制代码

_.random

返回一个 min 和 max 之间的随机整数。如果你只传递一个参数,那么将返回 0 和这个参数之间的整数。

_.random = function(min, max) {if (max == null) {max = min;min = 0;}return min + Math.floor(Math.random() * (max - min + 1));};
复制代码

注意:该随机值有可能是 min 或 max。

underscore 系列

underscore 系列目录地址:github.com/mqyqingfeng…。

underscore 系列预计写八篇左右,重点介绍 underscore 中的代码架构、链式调用、内部函数、模板引擎等内容,旨在帮助大家阅读源码,以及写出自己的 undercore。

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。

underscore 系列之防冲突与 Utility Functions相关推荐

  1. 打造属于自己的underscore系列(五)- 偏函数和函数柯里化

    这一节的内容,主要针对javascript函数式编程的两个重要概念,偏函数(partial application) 和函数柯里化(curry)进行介绍.着重讲解underscore中对于偏函数应用的 ...

  2. 打造属于自己的underscore系列 ( 一 ) - 框架设计

    underscore作为开发中比较常用的一个javascript工具库,提供了一套丰富的函数式编程功能,该库并没有拓展原有的javascript原生对象,而是在自定义的_对象上,提供了100多个方法函 ...

  3. underscore 系列之字符实体与 _.escape

    前言 underscore 提供了 _.escape 函数,用于转义 HTML 字符串,替换 &, <, >, ", ', 和 ` 字符为字符实体. _.escape(' ...

  4. 物联16:4 ISO/IEC 14443-3 防冲突、防碰撞算法、Type A、Type B

    ISO/IEC14443-3 防冲突.防碰撞算法.TypeA.Type B 防冲突原理 1 前言  当2张或2张以上的同类型的PICC卡同时进入RF(Radio Frequency)区域时,多张卡同时 ...

  5. 三天搞定射频识别技术(二)2.3寻卡防冲突选卡

    寻卡防冲突 /******************************************************************************* //功 能:寻卡 //参数 ...

  6. 射频卡(mifare)防冲突机制详解

    正常情况下读写器某一时刻只能对磁场中的一张射频卡进行读写操作.但是当多张卡片同时进入读写器的射频场时,读写器怎么办呢?读写器需要选出唯一的一张卡片进行读写操作,这就是防冲突. 防冲突机制是非接触式智能 ...

  7. nRF24L01+组网方式及防撞(防冲突)机制的实战分享

    nRF24L01+组网方式及防撞(防冲突)机制的实战分享 利用多个nRF24L01+模块组网通信的实现方式 防撞(防冲突)机制的实现原理 轮询方式一主多从 时分方式一主多从或多主多从 自主避让方式一主 ...

  8. 射频识别技术漫谈(32)——曼侧斯特码与FM0编码的防冲突原理

    [转自]http://blog.sina.com.cn/s/blog_9ed067ad0102vyl6.html 在RFID技术中,从低频的125KHz.134.2KHz到高频的13.56MHz,再到 ...

  9. H3C MS系列安防交换机测评报告

    安防行业是随着现代社会安全需求应运而生的产业.可以说,社会只要还有犯罪和不安定因素存在,安防行业就会存在并发展.事实证明,社会犯罪率往往并不因社会的发展.经济的繁荣而减少.欧美等发达国家,如果没有建立 ...

最新文章

  1. 2.Python中的reload函数以及not defined reload
  2. CF 1093 E. Intersection of Permutations
  3. SharePoint 2013 开发——SharePoint Designer 2013工作流
  4. Fastjson 爆出远程代码执行高危漏洞,更新版本已修复
  5. 软考已报名可以更改科目吗
  6. uboot通过使用U磁盘引导内核RT5350成功
  7. python包接口,Typetalk聊天API的python接口包
  8. 存储过程 not supported yet_让我们来看看+Redis如何存储和计算一亿用户的活跃度
  9. [Golang] string类型和其他类型的值的互转
  10. vue项目原理分析-2:路由
  11. python中的type函数-python的type函数
  12. ceph搭建_如何一键搭建并管理Filecoin集群节点 | Gamma OS新功能上线
  13. hibernate一对多映射实现
  14. 转载:你需要知道的16个Linux服务器监控命令
  15. 张一鸣在字节跳动7周年庆典上的演讲
  16. java运维工程师简历模板_系统运维工程师个人个人简历模板.doc
  17. Hibernate:DisjunctionConjunction构造复杂的查询条件.
  18. python绘制直方图
  19. 第二章 Binary Search
  20. 利用新浪API实现数据的抓取\微博数据爬取\微博爬虫

热门文章

  1. html回车按键确认按钮,button默认enter事件(回车事件)。
  2. 为什么6lowpan 要有四个地址_为什么你打玻尿酸,能被人一眼看出来?这四个地方要谨慎注射!...
  3. python最基本的两种循环结构_Python基础 — 分支和循环
  4. excel表格怎么调整行高和列宽_表格太宽,怎么打印在一页上?这招超简单
  5. java冒泡排序_JAVA实现经典排序算法(冒泡排序、选择排序、插入排序、希尔排序、堆排序、归并排序、快速排序)...
  6. 深入浅出springboot 下载_有没有相见恨晚的学习模电好方法?《新概念模拟电路》全五册合集免费下载...
  7. 【直播课】6小时教你熟知Anchor free理论基础,掌握项目实战技巧
  8. 【通知】3月第三周直播预告,模型精简前沿技术,人脸分析与编辑,图像风格化...
  9. lazada做代运营,价格越低越好吗?价格和价值分析
  10. 《微机原理及接口技术》第07章在线测试