每天学习API之三 ,zepto源码type, isFunction,isObject,isWindow,isDocument,isPlainObject,isArray,likeArray

数据类型检测

//定义

//定义

var classtype = {},
    toString = classtype.toString;


"Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(name,idx) {
  classtype['[object ' + name + ']'] = name.toLowerCase();
});

classtype的形式如下
classtype = {
  "[object Boolean]": "boolean",
  "[object Number]": "number"
  ...
};


function type(obj) {
  return obj != null ? String(obj) : classtype[toString.call(obj)] || 'obj';
}

type 函数返回的是数据类型
但有一点想不明白,为什么要这么麻烦,可以利用下面方法也可以得到数据类型而且更方便省事

function type2(obj) {
  return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}

isFunction & isObject;

function isFunction(value) {
  return type(value) === 'function';
}
function isObject(obj) {
  return type(obj) === 'object';
}

直接调用type函数,判断返回的类型字符串,即可得到数据类型了

isWindow

function isWindow(obj) {
  return obj != null && obj.window == window;
}

判断是否为浏览器对象
要为window对象首先满足的条件是不能为null 或者 undefined,并且obj.window为自身的引用

isDocument
function isDocument(obj) {
  return obj != null && obj.nodeType == obj.DOCUMENT.NODE;
}

判断是否为document对象
节点上面有 nodeType 属性,每个属性值都有对应的常量,document的nodeType 值 为9,常量为DOCUMENT_NODE

isPlainObject

function isPlainObject(obj) {
  return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype;
}

判断是否为纯粹对象
首先必须是对象 isObject(obj),并且不是window 对象 !isWindow(obj)
最后必须obj的原型要和Object的原型相等

isArray

isArray = Array.isArray || 
       function(object) { return object instanceof Array}

这个方法用来判断是否为数组对象
如果浏览器支持Array.isArray 就采用原生方法,否则就是用检测数据是否为Array的实例,
不知道为何作者这里这么写,也可以利用上面 判断数据类型的 type2方法


likeArray

function likeArray(obj) {
  var length = !!obj &&   // obj必须存在
                'length' in obj && // obj 中必须存在 length 属性
                obj.length, // 返回 length的值
      type = $.type(obj) // 调用 type 函数,返回 obj 的数据类型。这里我有点不太明白,为什么要覆盖掉上面定义的 type 函数呢?再定义多一个变量,直接调用 type 函数不好吗?

  return 'function' != type &&  // 不为function类型
        !isWindow(obj) &&  // 并且不为window类型
        (
            'array' == type || length === 0 || // 如果为 array 类型或者length 的值为 0,返回true
    (typeof length == 'number' && length > 0 && (length - 1) in obj)  // 或者 length 为数字,并且 length的值大于零,并且 length - 1 为 obj 的 key
  )
}

判断是否为数据是否为类数组。
类数组的形式如下:

likeArrayData = {
  '0': 0,
  '1': 1,
  "2": 2,
  length: 3
}

不过上面如果是Array 也会返回true,感觉不是很严谨,我们再来看看《JavaScript权威指南》中给出的判断方法,
但根据定义函数也有length(形参的个数)属性,也应该是类数组对象,但是如果o是一个函数, typeof o === 'function' 而非
'object' ,因此isArrayLike 会返回false 感觉是定义的不严谨造成的

function isArrayLike(o) {
  if(o &&                                    // o不是null、undefined等
     typeof o === 'object' &&                // o是对象
     isFinite(o.length) &&                   // o.length是有限数值
     o.length >= 0 &&                        // o.length为非负值
     o.length === Math.floor(o.length) &&    // o.length是整数
     o.length < 4294967296)                  // o.length < 2^32
     return true
  else
     return false
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值