underscore.js源码研究(4)

概述

很早就想研究underscore源码了,虽然underscore.js这个库有些过期了,可是我仍是想学习一下库的架构,函数式编程以及经常使用方法的编写这些方面的内容,又刚好没什么其它要研究的了,因此就告终研究underscore源码这一心愿吧。html

underscore.js源码研究(1)
underscore.js源码研究(2)
underscore.js源码研究(3)
underscore.js源码研究(4)
underscore.js源码研究(5)
underscore.js源码研究(6)
underscore.js源码研究(7)
underscore.js源码研究(8)node

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

类型判断

对于类型判断,大部分元素能够经过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属性segmentfault

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

isArray

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

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
相关文章
相关标签/搜索