Skip to content

Array

js
let arr = new Array();
let arr = [];

arr[0];
arr.at(-1); // 旧式浏览器需要 polyfills

queue 与 stack

队列(queue)是最常见的使用数组的方法之一。

栈是一种数据结构。

栈通常被被形容成一叠卡片:
要么在最上面添加卡片,要么从最上面拿走卡片。

FIFO 与 LIFO

队列,FIFO(First-In-First-Out),先进后出

栈, LIFO(Last-In-First-Out),后进先出

JavaScript 中,数组既 作 队列,也 作 栈

允许这样的操作的数据结构被称为 双端队列(deque)。

具体方法

push,pop,shift,unshift 都会对原本 Array 产生影响,即 .length 会发生改变。

push:add at 末尾

pop:remove at 末尾

shift:rmove at 队首

unshift:add at 队首

push 和 unshift 都是添加,而他们都可以一次性 添加 多个元素。

Array is Object

Array 是对象,但是不要以对象的形式 使用 Array。
因为 引擎会对 Array 进行优化。

不要这样做:

  • 添加 非数字的属性。如:arr.test = 5
  • 制造空洞。如:添加 arr[0],添加 arr[1000],但是 它们中间 什么都没有!
  • 以倒序填充数组。如:arr[1000]arr[999] 等等。

性能

队尾慢,队首快。

shift 操作必须做三件事:

  1. 移除索引为 0 的元素。
  2. 把所有的元素向左移动,把索引 1 改成 0,2 改成 1 以此类推,对其重新编号。
  3. 更新 length 属性。

数组里的元素越多,就越花时间,也就意味着 更多的内存操作。

而 pop 和 push 则不要挪动,它们只需:

  1. 在 尾部 处理元素
  2. 更新 length 属性。

迭代

for ... i 最快

for ... of 用于可迭代,不能获取 index

for ... in 不要用于 Array。会遍历出所有属性

length

不是数组里元素的个数,而是最大的数字索引值加一。

所以,清空数组最简单的方法:arr.length = 0

类型转换

Symbol.toPrimitive > valueOf > toString

Symbol.toPrimitive 的 hint 默认为 default

js
const arr = [1, 2, 3];

arr[Symbol.toPrimitive] = function (hint) {
  l(hint);

  return 1;
};

l("?" + []);
l([] === arr);

不要使用 == 比较数组

Symbol.toPrimitive

js
[] == []; // 不会出发 false
[0] == [0]; // 不会出发 false

0 == []; // default true

"0" == []; // default false
js
0 === []; // false

"0" === []; // false

== 适用于原始类型,引用类型 则 比较 引用。

=== 不会发生类型转换,但也仅此而已。