如果 randomId 是一个较大的数字,那么会在 temp 数组中留下很多空位。可能会导致很多 null
值。将 temp 从数组改为对象,以避免稀疏数组的问题。
稀疏数组:当一个数组中大部分元素为0,或者为同一值(也就是说可以不是0)的数组时
const randomId = ()=> { return Math.floor(Math.random() * 10000).toString() }
// let temp = []
let temp = {} // 调整为对象
function addData(data) {
const id = randomId()
// 将新数据插入到数组中
// temp.push({ id, ...data })
temp[id] = {...data}
}
addData({ name: "one", str: "hello" })
addData({ name: "two", str: "How are you" })
console.log(temp)
//[{id: '3473', name: 'one', str: 'hello'},{id: '3713', name: 'two', str: 'How are you'}]
// {8953:{name: 'two', str: 'How are you'},9750:{name: 'one', str: 'hello'}}
console.log(JSON.stringify(temp))
// [{"id":"4242","name":"one","str":"hello"},{"id":"5011","name":"two","str":"How are you"}]
// {"8953":{"name":"two","str":"How are you"},"9750":{"name":"one","str":"hello"}}
console.log(JSON.stringify({temp}))
// {"temp":[{"id":"916","name":"one","str":"hello"},{"id":"6342","name":"two","str":"How are you"}]}
// {"temp":{"8953":{"name":"two","str":"How are you"},"9750":{"name":"one","str":"hello"}}}
另:如果 randomId不做为索引值, 作为数组中每项的 id 的值 不会出现很多空值
let arr2 = []
arr2.push({id:"4242",name:"one",str:"hello"})
arr2.push({id:"5011",name:"two",str:"How are you"})
console.log(arr2)// [{id:"4242",name:"one",str:"hello"},{id:"5011",name:"two",str:"How are you"}]
let a = arr2.filter((item)=>item.id == '5011')
console.log(a)// [{id: '5011', name: 'two', str: 'How are you'}]
数组和对象的区别:
1. 数组:
- 数组是基于索引的集合,索引从0开始的连续整数
- 数组元素是有序的,适合用于需要保持元素顺序的场景
- 数组的长度是其最大索引加 1 ,如果数组中某些索引没有值,就会形成稀疏数组
例如,如果你创建一个数组 arr
并在索引 1000000 处放置一个值,而在这之前没有其他值,数组的长度将是 1000001,但只有索引 1000000 处有一个值,其余的索引都是空的(undefined),形成稀疏数组。
let arr = []
arr[1000000] = 'value'
console.log(arr.length) // 1000001
console.log(arr[999999]) // undefined
2. 对象:
- 对象是基于键值对的集合,键可以是字符串或symbol
- 对象属性是无序的,适合用于需要快速查找键值对的场景
- 对象的属性是动态,不需要连续的索引,因此不会出现稀疏问题
let obj = {}
obj[1000000] = 'value'
console.log(Object.keys(obj).length) // 1
console.log(obj[999999]) // undefined
为什么数组会变成稀疏数组 对象不会?
如果数组使用很大的索引值时,数组长度会自动扩展,但中间的元素没有被赋值,就会undefined,这些未被赋值的元素不会占用实际内存,但会影响数组的长度和某些操作的性能。
对象的属性是基于键值对的,不需要连续的索引。无论用多大的键,都会直接在对象中创建相应的属性,不会在对象内部产生空洞。因此对象不会向数组那样出现稀疏的问题。