lodash的isXXX方法们
_.isObject
是否为对象 (e.g. arrays, functions, objects, regexes,new Number(0)
, andnew String('')
)
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
实际上判断!!value
排除掉了null
和NaN
两种特殊值,
有可能会疑问,type == 'function'
,函数是对象的一种。
new string('')
在这里是被当作对象处理的。
以字符串为例,new String('')
这种我们称之为字符串对象,而我们常用的var str = ''
或者var str = String('')
,我们称之为基本字符串。当我们执行时,js会自动将基础字符串转换为字符串对象,再调用字符串原型上的方法。
_.isObjectLike
检查 value 是否是 类对象。 如果一个值是类对象,那么它不应该是 null,而且 typeof 后的结果是 "object"。
function isObjectLike(value){
return !!value && typeof value == 'object';
}
_.isPlainObject
查 value 是否是普通对象。 也就是说该对象由 Object 构造函数创建,或者 [[Prototype]] 为 null 。Native objects: Object (constructor), Date, Math, parseInt, eval, string methods like indexOf and replace, array methods, ...
Host objects (assuming browser environment): window, document, location, history, XMLHttpRequest, setTimeout, getElementsByTagName, querySelectorAll, ...
var objectTag = '[object Object]';
var getPrototype = overArg(Object.getPrototypeOf, Object);
function isPlainObject(value) {
if (!isObjectLike(value) || // 不是对象
objectToString.call(value) != objectTag || isHostObject(value)) {
/**
* - hostobject,像setTimeout,window.location.,window,document这种就是hostObject。
*
*/
return false;
}
var proto = getPrototype(value); //- 获取prototype.正如方法描述所说,如果没有proto,直接就返回true了。
if (proto === null) {
return true;
}
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return (typeof Ctor == 'function' &&
Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
}
constructor
返回创建实例对象的 Object 构造函数的引用.
如下例子
var Foo = function Foo(){}
var foo = new Foo();
foo.constructor === Foo;
// => true
// case 0 假如我们此时传的是foo,则Ctor实际上指的是
var Ctor = Foo.prototype.constructor
Foo.prototype.constructor.toString()
// => "function (){}"
Object.prototype.constructor.toString()
// => "function Object() { [native code] }" 当前结果为Object.toString()
_.isLength(value)
检查 value 是否为有效的类数组长度。
//js中最大的整数
var MAX_SAFE_INTEGER = 9007199254740991;
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
有效的数组长度有2个前提
- number类型
- 有效的正整数
_.isFunction
检查 value 是否是 Function 对象。
实际上,我们可以使用typeof fn === 'function'
来判断是否是数组,但是在某些环境(比如Safari8-9 会返回‘object’)。通过object.toString
规避了这个问题,提高了代码的健壮性。
Generator
的genTag
可以看这个issue https://github.com/lodash/lod...,这个问题,规避的是在nodejs中的问题。
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8-9 which returns 'object' for typed array and other constructors.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
_.isArray
判断是否数组
借用的是var isArray = Array.isArray
_.isArrayBuffer
检查 value 是否是 ArrayBuffer 对象。
var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
var arrayBufferTag = '[object ArrayBuffer]';
function baseIsArrayBuffer(value) {
return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
}
部分代码是跟node相关,暂不处理。从baseIsArrayBuffer看,仍是通过Object.toString返回的字符串做的判读。ArrayBuffer是es6中新增。
_.isArrayLike
是否类数组
该方法对类数组有个定义,value不是一个方法,并且value.length
是一个有效的值。(大于等于0,小于等于Number.MAX_SAFE_INTEGER
)
你可能要注意一下,字符串"abc"这种也被毁当作一个arraylike
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength(value.length) && !isFunction(value);
}
_.isArrayLikeObject
功能同isArrayLike
相同,只是它前提判断是否是一个对象。也就是'abc'
这种字符串返回false
function isArrayLikeObject(value) {
return isObjectLike(value) && isArrayLike(value);
}
_.isArguments
判断是否是类arguments对象
function isArguments(value) {
// Safari 8.1 makes `arguments.callee` enumerable in strict mode.
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
}
- arguments是类数组
- arguments有
callee
属性,指向当前执行的函数。 - arguments有length属性
- arguments[@@iterator]返回一个新的Array迭代器对象,该对象包含参数中每个索引的值。
- callee属性不可枚举
_.isBoolean
判断是否为Boolean类型
function isBoolean(value) {
return value === true || value === false ||
(isObjectLike(value) && objectToString.call(value) == boolTag);
}
对象这个判断可能会有点迷惑,实际上是证明了这种情况
var bol = new Boolean('true')
typeof bol
// object
_.isDate
是否为Date类型
var dateTag = '[object Date]';
function baseIsDate(value) {
return isObjectLike(value) && objectToString.call(value) == dateTag;
}
判断条件为value
是对象类型,在判断toString返回的值是否为[object Date]
_.isElement
是否为dom element
function isElement(value) {
return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
}
nodeType
是什么?http://www.w3school.com.cn/js...
如果节点是元素节点,返回1。
如果节点是属性节点,返回2.
所以判断是dom element是,是对象,是元素节点。
_.isEmpty
/**
* Checks if `value` is an empty object, collection, map, or set.
* 检查`value`是否是一个空的对象,collection,map或者set
* Objects are considered empty if they have no own enumerable string keyed
* properties.
* 如果对象没有以enumerable的字符串属性,被认为是空的。
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
* jQuery-like collections are considered empty if they have a `length` of `0`.
* 像arugments对象,数组,buffers,strings,或者jquery对象被认为是空的如果它们的length属性为0
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
*同样,maps和sets对象的length属性为空,我们也认为它是empty
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
* @example
*
* _.isEmpty(null);
* // => true
*
* _.isEmpty(true);
* // => true
*
* _.isEmpty(1);
* // => true
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty({ 'a': 1 });
* // => false
*/
function isEmpty(value) {
if (isArrayLike(value) &&
(isArray(value) || typeof value == 'string' ||
typeof value.splice == 'function' || isBuffer(value) || isArguments(value))) {
return !value.length;
}
var tag = getTag(value);
if (tag == mapTag || tag == setTag) { // map或者set类型,判断size存在,不存在是empty
return !value.size;
}
if (isPrototype(value)) { // 传入的是一个prototype对象,而且没有任何属性
return !nativeKeys(value).length;
}
for (var key in value) {
// 用for in 来判断value,如果value上key不是在原型链上,就有问题。
if (hasOwnProperty.call(value, key)) {
return false;
}
}
return true;
}
// isPrototype
/**
* Checks if `value` is likely a prototype object.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
*/
function isPrototype(value) {
var Ctor = value && value.constructor,
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
return value === proto;
}
判断圆形对象。
String.prototype.constructor.prototype === String.prototype
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。