类型判断

underscore 中提供了多个 isXXX 方法用以判断对象属于哪种 “类型”。

大部分元素都可以通过 Object.prototype.toString 的结果进行判断,比如:

var string = new String('wxj');
Object.prototype.toString.call(string); // => '[object String]'

对于这些类型,underscore 皆是通过 Object.prototype.toString 来进行类型判断:Arguments, Function, String, Number, Date, RegExp, Error, Symbol, Map, WeakMap, Set, WeakSet

_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function (name) {
  _['is' + name] = function (obj) {
      return toString.call(obj) === '[object ' + name + ']';
  };
});

_.isArguments(obj)

_.isArguments(obj):判断 obj 是否是 arguments

对于 Arguments 判断,IE9 以前的版本,Object.prototype.toString 返回的会是 '[object Object]' 而不是 '[object Arguments],需要通过判断对象是否具有 callee 来确定其是否为 Arguments 类型。underscore 对此进行了修正:

if (!_.isArguments(arguments)) {
  // 判断obj是否是argumens
  // 只有arguments才会有callee属性
  _.isArguments = function (obj) {
      return _.has(obj, 'callee');
  };
}

_.isFunction(obj)

_.isFunction(obj):判断 obj 是否是函数。

此外,underscore 还修正了在早期 V8 引擎下的对于对象是否为函数的判断:

var nodelist = root.document && root.document.childNodes;
if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
  _.isFunction = function (obj) {
      return typeof obj == 'function' || false;
  };
}

用例

_.isNumber(1/0);               // => true
_.isNumber('2');               // => false
_.isDate(new Date());          // => true
_.isString('');                // => true
_.isRegExp(/[0-9]/);           // => true
_.isError(new Error('error')); // => true
_.isSymbol(Symbol());          // => true

_.isElement(obj)

_.isElement(obj):判断 obj 是否是 DOM 节点

源码

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

该方法是通过 Node.nodeType 来判断元素是否为 DOM 节点。nodeType 的取值参看 MDN

用例

var body = document.getElementsByTagName('body')[0];
_.isElememt(body); // => true

_.isArray

_.isArray(obj):判断 obj 是否是数组

源码

_.isArray = nativeIsArray || function (obj) {
  return toString.call(obj) === '[object Array]';
};

对于数组的判断,优先使用ES5中的Array.isArray,否则通过Object.prototype.toString来进行判断。

用例

var arr = [1, 2, 3, 4];
_.isArray(arr); // => true

_.isObject

_.isObject(obj):判断 obj 是否是对象

源码

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

看到源码可以知道,函数也被视为对象,undefinednullNaN 等则不被认为是对象

用例

_.isObject(Object.keys); // => true
_.isObject(null); // => false
_.isObject(undefined); // => false
_.isObject(NaN); // => false
_.isObject({}); // => true

_.isFinite

_.isFinite:判断 obj 是否有限

源码

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

// 1.8.3
_.isFinite = function(obj) {
  return isFinite(obj) && !isNaN(parseFloat(obj));
};

该函数依赖于 JavaScript 全局提供的 isFiniteisFinite(obj) 之后为何还要接上 isNaN(parseFloat(obj)) 是进行一些修正,作者认为,bool 值不应当考虑其有限性:

isFinite(true); // => true
!isNaN(parseFloat(true)); // => false

isFinite(null); // => true
!isNaN(parseFloat(null)); // => false;

用例

_.isFinite('2000');   // true
_.isFinite(1/0);      // false
_.isFinite(Infinity); // false
_.isFinite(true);     // false
_.isFinite(null);     // false

_.isNaN

_.isNaN(obj):判断 obj 是否是一个非数字

源码

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

相比较原生的 isNaN(原生的 isNaN 会先传入参数转为数字),underscore 强制限定 NaN 必须为数字。

用例

// 我们对比原生的`NaN`和`_.NaN`
isNaN('NaN'); // => true
_.isNaN('NaN'); // => false
_.isNaN(NaN); // => true

isNaN(undefined); // => true
_.isNaN(undefined); // => false

_.isBoolean

_.isBoolean:判断 obj 是否是布尔类型

源码

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

用例

_.isBoolean(undefined); // => false
_.isBoolean(true); // => true

_.isNull

_.isNull:判断 obj 是否是 null

源码

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

用例

_.isNull(null); // => true

_.isUndefined

_.isUndefined:判断 obj 是否是 undefined

源码

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

用例

_.isUndefined(undefined); // => true

results matching ""

    No results matching ""