Lodash中isEmpty、isNull、isArray、isUndefined等各自实现及之间的区别
前言
在写项目过程中,看到了项目中某个文件中的自定义校验规则内一个if中条件写了一个
val === ''
,这时突然想到了lodash库中有一个isEmpty
方法,可以判断字符串是否为空,我便不假思索的将这一个判断给改成了isEmpty(val)
的写法,想着这样代码更优雅一些,但在我改完之后,新增数据时没有任何问题,当我修改这条数据的其他地方时,它的校验提示突然报红了,必须要将这个值重新写一遍才会通过校验,到了空闲的时候,去研究了一下官方文档上面的isEmpty实现和这块的代码,初步判断原因应该是因为代码的执行顺序造成的,也没有多想,只好先老老实实的将判断改回原来的样子了。今天我们就结合几个现实中经常用到的工具函数,来讲解一下如何解读复杂的运算符嵌套
isEmpty(value)
检查
value
是否为一个空对象,集合,映射或者set。 判断的依据是除非是有枚举属性的对象,length 大于 0 的 arguments object, array, string 或类jquery选择器。
空对象
对于空对象,loadsh 是这么解释的:
如果【对象没有自己的可枚举字符串键控属性】,则认为它们是空的,如果参数、对象、缓冲区、字符串或类似于jquery的集合等【类似数组的值的长度为0】,则认为它们为空。 类似地,如果【映射和集合的大小为0】,则认为它们是空的
对象如果被认为为空,那么他们没有自己的可枚举属性的对象。类数组值,比如arguments
对象,array,buffer,string或者类jQuery集合的length
为0
,被认为是空。类似的,map(映射)和set 的size
为0
,被认为是空。
isEmpty的源码实现
/**
*
* @example
*
* _.isEmpty(null);
* // => true
*
* _.isEmpty(true);
* // => true
*
* _.isEmpty(1);
* // => true
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty('abc');
* // => false
*
* _.isEmpty({ 'a': 1 });
* // => false
*/
function isEmpty(value) {
if (value == null) {
return true;
}
if (isArrayLike(value) &&
(isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
isBuffer(value) || isTypedArray(value) || isArguments(value))) {
return !value.length;
}
var tag = getTag(value);
if (tag == mapTag || tag == setTag) {
return !value.size;
}
if (isPrototype(value)) {
return !hasOwnProperty.call(value, 'constructor');
}
for (var key in value) {
if (hasOwnProperty.call(value, key)) {
return false;
}
}
return true;
}
看了这段代码,有些人可能就头疼了,就一个简单的
isEmpty
方法,居然写了这么多的判断,那么,这段代码具体是什么意思呢?
代码详解
- 检查
null
或undefined
:
- 如果
value
是null
或undefined
,则返回true
,表示空。- 检查类数组对象 :
- 如果
value
是类数组对象,并且是数组、字符串、具有splice
方法的对象、缓冲区对象、类型化数组对象或arguments
对象之一,并且其length
属性为0
,则返回true
,表示空。- 检查特定类型对象 :
- 如果
value
是Map
或Set
对象,并且其size
属性为0
,则返回true
,表示空。- 检查原型对象 :
- 如果
value
是原型对象,并且没有constructor
属性(即通过原型链继承的属性),则返回true
,表示空。- 遍历对象属性 :
- 如果
value
是普通对象,并且没有自身属性,则返回true
,表示空。- 否则,返回
false
,表示不为空。
isArray(value)
检查
value
是否是Array
类对象。
isArray的源码实现
/**
*
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
isArray
相对于isEmpty
而言,它的源码就显得通俗易懂
代码详解
Array.isArray
:
- 这个方法是 ES5 中引入的原生 JavaScript 方法。它用于检查一个值是否为数组,并返回一个布尔值,Lodash 的
isArray
方法直接使用了这个原生方法。
isNull(value)
检查
value
是否是null
。
isNull的源码实现
/**
*
* @example
*
* isNull(null)
* // => true
*
* isNull(void 0)
* // => false
*/
function isNull(value) {
return value === null;
}
isNull
相对于前几个而言,它的源码就显得更加的通俗易懂
代码详解
根据类型来判断value是否等于 null类型
isObject(value)
检查
value
是否为Object
的language type。 (例如: arrays, functions, objects, regexes,new Number(0)
, 以及new String('')
)
isObject的源码实现
/**
*
* @example
*
* isObject({})
* // => true
*
* isObject([1, 2, 3])
* // => true
*
* isObject(Function)
* // => true
*
* isObject(null)
* // => false
*/
function isObject(value) {
const type = typeof value;
return value != null && (type === 'object' || type === 'function');
}
isObject
也是相对比较容易理解的,根据value的类型来进行判断的
代码详解
typeof value
:返回一个表示value
类型的字符串,可能的值包括'undefined'
、'boolean'
、'number'
、'string'
、'symbol'
、'function'
和'object'
。value != null
:这个条件用于判断value
不是null
且不是undefined
。它相当于value !== null && value !== undefined
。(type === 'object' || type === 'function')
:这个条件用于判断value
的类型是否为'object'
或'function'
。在 JavaScript 中,函数也属于对象类型。
isUndefined(value)
检查
value
是否是undefined
.
isUndefined的源码实现
/**
*
* @example
*
* isUndefined(void 0)
* // => true
*
* isUndefined(null)
* // => false
*/
function isUndefined(value) {
return value === undefined;
}
isUndefined
和isNull
实现时基本一致的,都是之间根据类型来判断的
代码详解
根据类型来判断value是否等于undefined类型
不同点
举了这么多的例子,其他的方法我们就不一一举例了,实现方式都是大同小异,有兴趣的朋友可以到GitHub或lodash官网来看其他方法的实现,写了这么多,不知道有没有人发现第一个isEmpty中,其实在某些特点的时候,是可以用来代替下面的任何一种方法的
isEmpty(null)
&& isNull(null)
Lodash 的
_.isEmpty
函数用于检查一个值是否为空。它的工作原理如下:
对于对象和数组,检查它们的长度或属性数量。
对于其他原始类型(如字符串、数字等),返回它们是否是“空”的。
特别地,对于
null
和undefined
,_.isEmpty
会返回true
。_.isEmpty(null); // true _.isEmpty(undefined); // true _.isEmpty(''); // true _.isEmpty([]); // true _.isEmpty({}); // true _.isEmpty(0); // true _.isEmpty(false); // true
Lodash 的
_.isNull
函数用于检查一个值是否严格等于null
。它的工作原理如下:
仅当值严格等于
null
时返回true
。对于其他所有值,返回
false
。_.isNull(null); // true _.isNull(undefined); // false _.isNull(''); //回 false _.isNull([]); //false _.isNull({}); // false _.isNull(0); // false _.isNull(false); // false
总结
_.isEmpty(null)
检查null
是否为空,这会返回true
,因为null
被认为是“空”的。_.isNull(null)
检查值是否严格等于null
,这会返回true
,但仅在值是null
时才会返回true
因此,_.isEmpty(null)
和 _.isNull(null)
的区别在于前者检查值是否为空(包括 null
、undefined
、空字符串、空数组、空对象等),而后者仅检查值是否严格等于 null
。
isEmpty([])
&&isArray([])
Lodash 的
_.isEmpty
函数在上面已经写过工作原理,这里就不赘述了,直接说isArray的工作原理
Lodash 的_.isArray
函数用于检查一个值是否为数组。它专门用来确定值是否属于 JavaScript 中的数组类型。它的工作原理如下:isArray([]) // true isArray({}) // false isArray('') // false isArray(null) // false isArray(undefined) // false isArray(0) // false isArray(false) // false
总结
isEmpty
主要用于检查值是否为空,而不仅仅是数组。它能够处理数组、对象、字符串等多种类型。如果对象、数组中有值则返回false,isArray
专门用于确定一个值是否为数组类型。- 根据
isEmpty
的特性,在一些特定情况下判断数组的长度或对象的长度是否为0时可以用isEmpty
方法来判断,如果isEmpty(val)
返回true
,则代表它是空数组或空对象
所以,使用 isEmpty([1,2,3])
和 isArray([1,2,3])
的结果是不同的:isEmpty([1,2,3])
返回 false
,而 isArray([1,2,3])
返回 true
,因为 [1,2,3]
确实是一个数组。
标题:Lodash中isEmpty、isNull、isArray、isUndefined等各自实现及之间的区别
作者:mcwu
地址:http://mcongblog.com/articles/2024/06/28/1719562798284.html