Why underscore

最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中。

阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的 hack,更可以学到作者的整体设计思路以及 API 设计的原理(向后兼容)。

之后楼主会写一系列的文章跟大家分享在源码阅读中学习到的知识。

欢迎围观~ (如果有兴趣,欢迎 star & watch~)您的关注是楼主继续写作的动力

类型判断

第一篇跟大家简单地聊了下为什么 underscore.js 用 void 0 代替了 undefined,意外地收到了不错的反响,有朋友私信我说以前还真不知道这回事,也有人催促我赶紧继续下一篇解读文章。今天就跟大家聊一聊 underscore.js 中一些 JavaScript 常用类型检查方法,以及一些工具类的判断方法。

我们先说个老生常谈的问题,JavaScript 中数组类型的判断方法,事实上,我在 Javascript中判断数组的正确姿势 一文中已经详细分析了各种判断方式的优缺点,并给出了正确的判断代码:

function isArray(a) {
  Array.isArray ? Array.isArray(a) : Object.prototype.toString.call(a) === '[object Array]';
}

而 underscore 其实也正是这么做的:

// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
// 判断是否为数组
_.isArray = nativeIsArray || function(obj) {
  return toString.call(obj) === '[object Array]';
};

nativeIsArray 正是 ES5 中 Array.isArray 方法,如果支持则优先调用;而 toString 变量就保存了 Object.prototype.toString。

如何判断对象?underscore 把类型为 function 和 object 的变量都算作对象,当然得除去 null。

// Is a given variable an object?
// 判断是否为对象
// 这里的对象包括 function 和 object
_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

再看 'Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error' 这些类型的判断,其实都可以用 Object.prototype.toString.call 来判断,所以写在了一起:

// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
// 其他类型判断
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
  _['is' + name] = function(obj) {
    return toString.call(obj) === '[object ' + name + ']';
  };
});

但是看 isArguments 方法,在 IE < 9 下对 arguments 调用 Object.prototype.toString.call,结果是 [object Object],而并非我们期望的 [object Arguments]。咋整?我们可以用该元素是否含有 callee 属性来判断,众所周时,arguments.callee 能返回当前 arguments 所在的函数。

// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
// _.isArguments 方法在 IE < 9 下的兼容
// IE < 9 下对 arguments 调用 Object.prototype.toString.call 方法
// 结果是 [object Object]
// 而并非我们期望的 [object Arguments]。
// so 用是否含有 callee 属性来判断
if (!_.isArguments(arguments)) {
  _.isArguments = function(obj) {
    return _.has(obj, 'callee');
  };
}

工具类判断方法

接下来看下一些常用的工具类判断方法。

判断一个元素是否是 DOM 元素,非常简单,只需要保证它不为空,且 nodeType 属性为 1:

// Is a given value a DOM element?
// 判断是否为 DOM 元素
_.isElement = function(obj) {
  // 确保 obj 不是 null
  // 并且 obj.nodeType === 1
  return !!(obj && obj.nodeType === 1);
};

如何判断一个元素为 NaN?NaN 其实是属于 Number 类型,Object.prototype.toString.call(NaN) 返回的是 "[object Number]",而且 NaN 不等于本身,利用这两点即可进行判断:

// Is the given value `NaN`? (NaN is the only number which does not equal itself).
// 判断是否是 NaN
// NaN 是唯一的一个 `自己不等于自己` 的 number 类型
_.isNaN = function(obj) {
  return _.isNumber(obj) && obj !== +obj;
};

当然,underscore 还有很多其他的有用的工具类判断方法,具体可以看源码 https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js#L1192-L1263 这部分。

如果您觉得我分享的东西对您有所帮助,请关注我的 Repo https://github.com/hanzichi/underscore-analysis

【跟着子迟品 underscore】常用类型判断以及一些有用的工具方法的更多相关文章

  1. Underscore.js 常用类型判断以及一些有用的工具方法

    1. 常用类型判断以及一些有用的工具方法 underscore.js 中一些 JavaScript 常用类型检查方法,以及一些工具类的判断方法. 首先我们先来谈一谈数组类型的判断.先贴出我自己封装好的 ...

  2. 【跟着子迟品 underscore】JavaScript 数组展开以及重要的内部方法 flatten

    Why underscore (觉得这一段眼熟的童鞋可以直接跳到正文了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  3. 【跟着子迟品 underscore】JavaScript 中如何判断两个元素是否 "相同"

    Why underscore 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. 阅读一些著名框架类库的源码,就好像和一个个大师对 ...

  4. 【跟着子迟品 underscore】如何优雅地写一个『在数组中寻找指定元素』的方法

    Why underscore (觉得这部分眼熟的可以直接跳到下一段了...) 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. ...

  5. 【跟着子迟品 underscore】Array Functions 相关源码拾遗 & 小结

    Why underscore 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. 阅读一些著名框架类库的源码,就好像和一个个大师对 ...

  6. 【跟着子迟品 underscore】Object Functions 相关源码拾遗 & 小结

    Why underscore 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. 阅读一些著名框架类库的源码,就好像和一个个大师对 ...

  7. 【跟着子迟品 underscore】for ... in 存在的浏览器兼容问题你造吗

    Why underscore 最近开始看 underscore.js 源码,并将 underscore.js 源码解读 放在了我的 2016 计划中. 阅读一些著名框架类库的源码,就好像和一个个大师对 ...

  8. 【跟着子迟品underscore】从用 `void 0` 代替 `undefined` 说起

    Why underscore 最近开始看 underscore源码,并将 underscore源码解读 放在了我的 2016计划 中. 阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多 ...

  9. 第1节 Scala基础语法:5、6、7、8、基础-申明变量和常用类型,表达式,循环,定义方法和函数

    4.    Scala基础 4.1.   声明变量 package cn.itcast.scala object VariableDemo {   def main(args: Array[Strin ...

随机推荐

  1. AlloyRenderingEngine入门

    写在前面 AlloyRenderingEngine是一款非常快速的渲染引擎,目前该项目已经合并至 https://github.com/AlloyTeam/AlloyGameEngine/ , 属于A ...

  2. html的meta总结,html标签中meta属性使用介绍

    引用:http://www.haorooms.com/post/html_meta_ds 前言 meta是html语言head区的一个辅助性标签.也许你认为这些代码可有可无.其实如果你能够用好meta ...

  3. 网页端实现input数字输入框

    实现input输入框只能输入数字的效果: <input type="text" name="" id="phoneNum" value ...

  4. GIS公交查询-flex/java

    开发语言是flex.java,开发平台是myeclise.eclise,开发接口是arcgis api for flex,提供以下的功能: 1.站名-站名查询: 2.站点查询: 3.路线查询: 备注: ...

  5. gcc boost版本冲突解决日记

    问题背景 项目在Ubuntu10 64位 boost 1.55,boost采用的是项目内包含相对目录的形式部署 项目采用了 -Wall -Wextra -Werror -Wconversion 最高的 ...

  6. 多人开发Xcode工程冲突,打不开解决办法

    在公司多人协作开发,相信好多程序员都遇到非常忧伤的问题,就是工程打不开,这样就无从下手,好多程序怨只能再从代码服务器上下载一份新的代码,今天军哥教你几个小技巧,让你的bigger瞬间提升一个档次 在公 ...

  7. 使用adjacent_difference要注意的小问题

    adjacent_difference的源与目的地可以相同,这是在标准中说明的,所以我产生了疑问,会不会因为这样使用而改变了当前成员,而影响下一步计算呢,经试验,在vs2015里并不会. #inclu ...

  8. [LoadRunner]LR11安装或破解时报错的解决方法

    背景:在性能测试项目上,需要安装到LR11进行性能测试,而在安装时会出现安装运行环境失败,安装文件缺失等问题.现总结了上述问题,并给出以下解决方法: 问题1:安装LoadRunner时出现“计算机缺少 ...

  9. ORACLE表空间管理维护

    1:表空间概念 在ORACLE数据库中,所有数据从逻辑结构上看都是存放在表空间当中,当然表空间下还有段.区.块等逻辑结构.从物理结构上看是放在数据文件中.一个表空间可由多个数据文件组成. 如下图所示, ...

  10. ORACLE 移动数据文件 控制文件 重做日志文件

    ORACLE数据库有时候需要对存储进行调整,增加分区.IO调优等等,此时需要移动数据文件.重做日志文件.控制文件等等,下文结合例子总结一下这方面的知识点. 进行数据文件.重做日志文件.控制文件的迁移前 ...