概述

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

underscore.js源码研究(1)

underscore.js源码研究(2)

underscore.js源码研究(3)

underscore.js源码研究(4)

underscore.js源码研究(5)

underscore.js源码研究(6)

underscore.js源码研究(7)

underscore.js源码研究(8)

参考资料:underscore.js官方注释undersercore 源码分析undersercore 源码分析 segmentfault

类型判断

对于类型判断,大部分元素可以通过Object.prototype.toString的结果进行判断,包括:Arguments, Function, String, Number, Date, RegExp, Symbol, Map, WeakMap, Set, WeakSet。实例如下:

//判断是否为函数,判断其他的只要把下面的Function改成其它的就可以了
function isFunction (obj) {
return Object.prototype.toString.call(obj) === '[object Function]';
} //建立一个函数
var haha = function haha() {
consolog.log('haha');
} console.log(isFunction(haha)); //输出true
console.log(isFunction(123)); //输出false

注意,IE9 以前的版本以及早期 V8 引擎对类型判断有一些小bug,underscore.js修复了这些问题,具体可自行查看underscore.js源码

isElement

判断是否为DOM节点,使用nodeType属性

function isElement(obj) {
return !!(obj && obj.nodeType === 1);
}

isArray

判断是否为数组,优先使用Array.isArray,不支持则使用Object.prototype.toString

var isArray = Array.isArray || function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}

isObject

使用typeof来判断是否为对象。

function isObject(obj) {
var type = typeof obj;
return type === 'function' || type ==='object' && !!obj;
}

可以看到,函数会被判断为对象,空对象{},undefined,null,NaN 等则不被认为是对象。

isFinite

判断是否有限。主要是使用js全局提供的isFinite函数来判断。

function isFinite(obj) {
return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));
}

最后那个!isNaN(parseFloat(obj))是为了排除bool值。

isNaN

判断是否为NaN,主要通过js全局提供的isNaN来判断。

function isNaN(obj) {
return _.isNumber(obj) && isNaN(obj);
}

is Boolean

判断是否为Boolean。

function isBoolean(obj) {
return obj === true || obj === false || Object.prototype.toString.call(obj) === '[object Boolean]';
}

isNull

判断是否是null,直接判断即可。

function isNull(obj) {
return obj === null;
}

isUndefined

判断是否是undefined,利用void 0。

function isUndefined(obj) {
return obj === void 0;
}

相等性判断

很多时候我们都要判断2个元素的相等性,在这个时候我们可以先判断它们的类型,然后再判断它们的值。可以有一些特殊的情况:

  • 0 === -0
  • null == undefined
  • NaN != NaN
  • NaN !== NaN

它们的解决方案如下:

  • 1/0 === 1/0; 1/-0 !== 1/0
  • null === null; null !== undefined;
  • if(a !== a) return b !== b;

这里我不打算写一般的比较情况,只是把几个特殊的情况写一下:

正则表达式和字符串

主要是转化为字符串再比较

Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return '' + a === '' + b;
}

数字

需要排除0和NaN的情况,并且利用+a把a转化为数字

Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
}

日期和布尔值

利用+a把a转化为数字

Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return +a === +b;
}

Symbol

利用SymbolProto.valueOf方法。

Eq = function(a, b) {
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
}

注意:不能直接用''或者'='来判断对象的相等性,原因如下:

var a = new Object();
var b = new Object();
a.name = "mm";
b.name = "mm";
console.log(a == b); //false

underscore.js源码研究(4)的更多相关文章

  1. underscore.js源码研究(8)

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

  2. underscore.js源码研究(7)

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

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

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

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

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

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

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

  6. underscore.js源码研究(2)

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

  7. underscore.js源码研究(1)

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

  8. underscore.js源码解析(五)—— 完结篇

    最近公司各种上线,所以回家略感疲惫就懒得写了,这次我准备把剩下的所有方法全部分析完,可能篇幅过长...那么废话不多说让我们进入正题. 没看过前几篇的可以猛戳这里: underscore.js源码解析( ...

  9. underscore.js 源码

    underscore.js 源码 underscore]JavaScript 中如何判断两个元素是否 "相同" Why underscore 最近开始看 underscore.js ...

随机推荐

  1. mybatis拦截器案例之获取结果集总条数

    最近做的项目前端是外包出去的,所以在做查询分页的时候比较麻烦 我们需要先吧结果集的条数返回给前端,然后由前端根据页面情况(当前页码,每页显示条数)将所需参数传到后端. 由于在项目搭建的时候,是没有考虑 ...

  2. java正则表达式笔记

    import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntax ...

  3. vue 开发系列(一) vue 开发环境搭建

    概要 目前前端开发技术越来越像后台开发了,有一站式的解决方案. 1.JS包的依赖管理像MAVEN. 2.JS代码编译打包. 3.组件式的开发. vue 是一个前端的一站式的前端解决方案,从项目的初始化 ...

  4. VIP之MixerII

    1.VIP Mixer IIMixerII的每一个输入通道都必须通过Frame Buffer来或者Frame Reader驱动,才能保证数据在正确的时间送入到MixerII中.Downscale不能把 ...

  5. Silverlight中Image控件Stretch属性的四种值比较

    通过设置Image控件Stretch属性的值可以控制图片的显示形式: 包含的值:None.Fill.Uniform.UniformToFill <Grid x:Name="Layout ...

  6. Vue上传文件:ElementUI中的upload实现

    一.上传文件实现 两种实现方式: 1.直接action <el-upload  .利用before-upload属性 此种方式有个弊端,就是action是必选的参数,那么action如果和pos ...

  7. 利用nginx打造个人简历网页

    1.下载nginx nginx官方网址:http://nginx.org/ 2.下载和解压 #下载:[root@iZwz9cl4i8oy1reej7o8pmZ soft]# wget http://n ...

  8. Spring的下载与安装

    Spring是一个独立的框架,不依赖于任何Web服务器或容器.它既可在独立的JavaSE项目中使用,也可以在Java Web项目中使用. 下载和安装Spring框架可按如下步骤进行: 1.登录http ...

  9. 深入浅出javascript(二)函数和this对象

    一.函数对象的属性和方法 函数是一种数据类型,也是对象,这一点很明确.因此,函数对象也可以添加属性和方法,但是这里的属性和方法是静态的,之所以这样说,就是为了区别构造函数. 示例如下: ①创建一个空的 ...

  10. slice()

    提取字符串中的一部分,并返回这个新的字符串 str.slice(beginSlice[, endSlice]) 参数 beginSlice 从该索引(以 0 为基数)处开始提取原字符串中的字符.如果值 ...