underscore相关记录

为什么使用void 0代替undefined? 

  在很多框架的源码以及webpack打包出来的bundle.js中,我们都可以看到void 0的身影,如下:

function generateRandomKey() {
  var key = void 0;
  while (key === undefined || seenKeys.hasOwnProperty(key) || !isNaN(+key)) {
    key = Math.floor(Math.random() * MULTIPLIER).toString(32);
  }
  seenKeys[key] = true;
  return key;
}

  

module.exports = function shallowEqual(objA, objB, compare, compareContext) {

    var ret = compare ? compare.call(compareContext, objA, objB) : void 0;

    if(ret !== void 0) {
        return !!ret;
    }

  在浏览器中运行,可以发现,void 0的返回值就是undefined,即通过这种方式将某个变量赋值为 undefined,但是为什么不直接赋值呢? 为什么需要使用 void 0 这种方式呢?我认为有以下几点原因:

  • 在IE中,直接给变量赋值为undefined后,这个变量还可以重写,但是chrome等浏览器不会。
  • 在chrome下的某个全局变量直接赋值为undefined,不会被重写,但是在局部作用域中如何也被赋值为 undefined,那么这个值还可以被重写。
  • void 0在大量使用的时候,一定会比 undefined 所占用的字节少。

类型判断的常用方法

  比如判断数组可以使用下面的方法:

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

  其中 Array.isArray() 方法是ES5内置的判断数组的方法,如果支持就使用;如果不支持,就使用通用的 Object.prototype.toString.call() 。 因为前者更为简洁,效率更高,后者更为通用。

  

  当判断对象时,我们可以认为function也是对象,但是null一般需要排除掉,那么判断的方式可以是下面这样的:

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

   可以看到,比较通用的方式就是使用 typeof,之所以数组不这么使用,是因为数组使用 typeof 得到的也是对象,所以才需要通过一些其他方法。

   类似的,如果我们希望判断  'Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'  这些类型时,也都可以通过使用 Object.prototype.toString.call() 这种比较通用的方式进行判断,使用understore的方式如下:

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

  其中,_each就是underscore中对each方法的一个封装,而toString.call()实际上就是Object.prototype.toString.call()方法。 

  而在IE9以下的浏览器中,对于argument我们得到的时[object Object],所以,我们还需要再添加一层判断,就是是否具有callee属性。

  

  另外,如果我们希望判断DOM元素时,只需要知道这个元素不是空的,并且其nodeType为1即可,如下所示:

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

  

  

   那么如何判断NaN类型呢? 通过Object.prototype.toString.call(),我们可以判断出来NaN类型得到的时[object Number], 而NaN又是Number中唯一一个自己不等于自己的数,所以:

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

  另外我们是可以首先判断是否支持 isNaN() 方法,如果支持,就可以先用 isNaN 来判断,然后再使用上面的方法。

  

  

原文地址:https://www.cnblogs.com/zhuzhenwei918/p/7372001.html