数组中的empty剖析

数组中的empty剖析

一、首先empty是怎么来的

直接通过new Array来新建,手动修改数组的length,逗号之间没有任何数据等

const array = new Array(3);
console.log(array); //*  (3) [empty × 3]

const array2 = [1, , 3];
console.log(array2); //*  [1, empty, 3]

二、如何理解empty

但是按理说,未申明一个变量的值为undefined,这里不应该打印出[1, undefined, 3]么,这里为什么会打印出empty,而不是undefined呢?

const array2 = [1, , 3];
console.log(array2); //*  [1, empty, 3]
console.log(array2[1]); //* undefined

又为什么我们打印数组中该empty位置的时候,却又输出undefined呢?

其实,js中万物皆对象,数组底层也是对象,函数底层也是对象;

那什么是对象呢?

对象就是一系列属性名值对,即某个属性名对应某个属性值;当我们遍历对象时,不在对象中的属性当然不会被访问到。

而在JS中,数组就是对象,甚至数组的一些遍历方法,在内部执行的时候,都是先将数组转化为对象。

可以使用console.dir() 来查看数组对象中的所有属性。

console.dir() 方法可以显示指定 JavaScript 对象的属性列表,并以交互式的形式展现。输出结果呈现为分层列表,包含展开/折叠的三角形图标,可用于查看子对象的内容。

换句话说,console.dir() 是一种在控制台中查看指定 JavaScript 对象的所有属性的方法,开发人员可以通过这种方式轻松获取对象的属性。

—— 引用于MDN之console.dir的使用

可以使用in来判断指定的属性是否在该对象或其原型链中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QwE9RSU0-1686624426931)(/Users/haoyuzhang/Library/Application Support/typora-user-images/image-20230506181259748.png)]

这个array2是一个长度为3的{0: 1, 2: 3}对象,没有索引为1的数组第二个元素,即数组的空元素empty表示空位;

也就是说,empty表示空位,数组对象没有该位置的索引属性!!!既没有属性,也没有属性值;

但是为什么「console.log(array[2]); //* undefined」呢?

因为可以输出一个对象中”不存在的属性“的值

const obj = {0: 1, 2: 3};
console.log(obj[1]); //* undefined

但是[1, , 3]又和[1, undefined, 3]的区别是什么呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FyGvOPyj-1686624426932)(/Users/haoyuzhang/Library/Application Support/typora-user-images/image-20230506181925928.png)]

这个array3是一个长度为3的{0: 1, 1: undefined, 2: 3}对象,索引为1的数组第二个元素 值为undefined;

undefined是一种数据类型, 在数组中表示这个位置的值未定义, 但它仍然指向某个内存地址, 这个内存地址指向的是undefined;

三、数组中的empty、undefined、null的区别

使用数组的forEach、map等方法遍历时会自动忽略空位跳过循环, 而使用for循环则会将empty转换为undefined并遍历.

empty表明一个空位;

undefined表明了一个变量未定义;

null,空指针,指向了一个empty的指针,特指对象的值未设置

typeof null        // "object" (因为一些以前的原因而不是'null')
typeof undefined   // "undefined"
null === undefined // false
null  == undefined // true
null === null // true
null == null // true
undefined == undefined // true
!null //true
isNaN(1 + null) // false
isNaN(1 + undefined) // true
/**
 * Checks if `value` is `null`.
 *
 * isNull(null)
 * // => true
 *
 * isNull(void 0)
 * // => false
 */
function isNull(value) {
  return value === null
}

/**
 * Checks if `value` is `null` or `undefined`.
 * isNil(null)
 * // => true
 *
 * isNil(void 0)
 * // => true
 *
 * isNil(NaN)
 * // => false
 */
function isNil(value) {
  return value == null
}

四、如何理解forEach/map对数组中empty的怪异行为

因为在forEach/map底层在遍历的时候,会先判断该对象“坑位对应的索引”的属性是否存在,不存在的话则跳过循环;

const forEach = (arr, callback) => {
	const len = arr.length; //? arr的长度
	for (const i = 0; i < len; i++) {
		if (i in arr) { //* 如果索引存在于数组对象中,调用回调函数
			callback(arr[i], i, arr);
		}
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值