【underscore.js 源码解读】经常使用范例推断以及一些有效的东西要领

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

    原文作者:fish
    原文地址: https://segmentfault.com/a/1190000005173369
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞