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集合的length0,被认为是空。类似的,map(映射)和set 的size0,被认为是空。

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方法,居然写了这么多的判断,那么,这段代码具体是什么意思呢?

代码详解

  • 检查 nullundefined
    • 如果 valuenullundefined,则返回 true,表示空。
  • 检查类数组对象
    • 如果 value 是类数组对象,并且是数组、字符串、具有 splice 方法的对象、缓冲区对象、类型化数组对象或 arguments 对象之一,并且其 length 属性为 0,则返回 true,表示空。
  • 检查特定类型对象
    • 如果 valueMapSet 对象,并且其 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 是否为 Objectlanguage 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的类型来进行判断的

代码详解

  1. typeof value:返回一个表示 value 类型的字符串,可能的值包括 'undefined''boolean''number''string''symbol''function''object'
  2. value != null:这个条件用于判断 value 不是 null 且不是 undefined。它相当于 value !== null && value !== undefined
  3. (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;
}

isUndefinedisNull实现时基本一致的,都是之间根据类型来判断的

代码详解

根据类型来判断value是否等于undefined类型

不同点

举了这么多的例子,其他的方法我们就不一一举例了,实现方式都是大同小异,有兴趣的朋友可以到GitHublodash官网来看其他方法的实现,写了这么多,不知道有没有人发现第一个isEmpty中,其实在某些特点的时候,是可以用来代替下面的任何一种方法的

isEmpty(null) && isNull(null)

Lodash 的 _.isEmpty 函数用于检查一个值是否为空。它的工作原理如下:

  • 对于对象和数组,检查它们的长度或属性数量。

  • 对于其他原始类型(如字符串、数字等),返回它们是否是“空”的。

  • 特别地,对于 nullundefined_.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) 的区别在于前者检查值是否为空(包括 nullundefined、空字符串、空数组、空对象等),而后者仅检查值是否严格等于 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

    评论
    0 评论
avatar

取消