本文详细介绍了 Array 相关的知识,从伪码实现的角度去学习数组 API 使用和实现步骤。
API 汇总表:
Array | Array.from |
Array(构造函数)
Array(...vals)
和 new Array(...vals)
都可以用来创建数组。
使用方式都一样
如果只有一个参数的时个会创建一个长度为 vals[0] 的数组,里面的元素值为空。
如果有一个以上的参数时,会当做元素处理,创建一个长度为参数数量的数组,数组元素就 是传进来的参数值。
如: 一个长度为 1 的数组
|
|
[<1 empty item>]
一个长度为 2 的数组,元素有 [1,2]
|
|
[1 (\, 2)]
构造函数:
|
|
[<1 empty item>]
|
|
[1 (\, 2)]
第一个参数非数值类型时,当做元素处理,去创建长度为 1 的数组:
|
|
[[1 (\, 2)]]
如果是字符串数呢?
|
|
3 undefined
还是当做元素了。
伪码实现:
|
|
从伪码实现中总结出,需要关注的两点:
索引值是一个 uint32 类型的值,所以如果超出这个范围会发生异常
数组的索引实际上是以字符串形式存在的
无符号整型的范围是:
|
|
{ min: 0, max: 4294967296 } undefined
测试 1, 2
|
|
max: 4294967295 Invalid array length a has key "0" false a has key 0 false b has key "0" true b has key 0 true undefined
事实上 hasOwnProperty
内部实现会先将参数转成字符串之后再去找。
构造函数上的函数(Array.xxx)
构造函数上的函数是只能通过构造函数去掉用的
Array.from(items[,mapfn[, thisArg]])
处理分为两步:
是不是集合类型,如果是可直接使用迭代器去遍历 items
如果不是集合类型,可能是类数组类型,类数组类型都会 length 属性,所以从这个入 手去取值
|
|
测试:
|
|
> [ 1, 2, 3 ] > [ 1, 2, 3, 2 ] > [ undefined, undefined, undefined ] > [ undefined, undefined, undefined ] > [ 0, undefined, undefined ] > [ undefined, 1, undefined ] > [ undefined, undefined, 2 ] > [ 0, '1', 2 ] undefined
如果不想 new Array(3) 创建的数组在 map 等函数迭达不到可以使用 Array.form(new
Array(3))
处理一层。
|
|
forEach with Array.form undefined forEach with Array.form undefined forEach with Array.form undefined undefined
如 🔗 伪码 中实现,经过 Array.from 之后会给 hole 元素创建索引,值变成 undefined,从而就可以被迭达出来。
Array.isArray(arg)
Array.of(…items)
原型函数(方法, Array.prototype.xxx)
原型上的函数只能通过实例去调用,如:
var a = new Array(); a.push(1);