介绍
当我在Frontend Masters上深入研究Primeagen's Algorithms课程时,我被一个启示所震惊:我们用来声明JavaScript中的阵列的熟悉的const a = [ ]
语法实际上并不是传统意义上的阵列。这一发现令我感到惊讶,我感到渴望通过此博客与他人分享这种新发现的知识。
什么是数组?
数组是有序的值集合。每个值称为元素,每个元素在数组中具有数字位置,称为其索引。 JavaScript数组是未构图的:一个数组元素可能是任何类型的类型,并且同一数组的不同元素可能是不同类型的。数组元素甚至可能是对象或其他数组,它使您可以创建复杂的数据结构,例如对象和数组数组的数组。 JavaScript数组可能很稀疏:元素不需要连续索引,并且可能存在空白。每个JavaScript数组都有一个长度属性。对于Nonsparse数组,此属性指定数组中的元素数量。对于稀疏阵列,长度大于任何元素的最高索引。 JavaScript数组是JavaScript对象的一种专业形式,并且数组索引实际上只不过是恰好是整数的属性名称。 JavaScript数组是动态的:它们会根据需要生长或缩小,并且在您创建它时,无需声明数组的固定尺寸或在大小更改时重新分配它。
证据!
让我们为经验测试编写一些代码,并在引擎盖下找出什么类型的数据结构是 const a = []
P.S :我将使用TypeScript进行此证明,因此我有类型的安全性。
您可以在github repo中找到代码以供参考,也可以从下面复制并在您自己的计算机上进行处理
const a: number[] = [];
function time(fn: () => void): number {
const now = Date.now();
fn();
return Date.now() - now;
}
function unshift(number: number) {
for (let i = 0; i < number; ++i) {
a.unshift(Math.random());
}
}
function shift(number: number) {
for (let i = 0; i < number; ++i) {
a.shift();
}
}
function push(number: number) {
for (let i = 0; i < number; ++i) {
a.push(Math.random());
}
}
function pop(number: number) {
for (let i = 0; i < number; ++i) {
a.pop();
}
}
function get(idx: number) {
return function() {
return a[idx];
};
}
function push_arr(count: number) {
return function() {
push(count);
};
}
function pop_arr(count: number) {
return function() {
pop(count);
};
}
function unshift_arr(count: number) {
return function() {
unshift(count);
};
}
function shift_arr(count: number) {
return function() {
shift(count);
};
}
让我们总结:
-
创建一个数组
-
函数
time:
测量函数时间我们只想估计事物的速度或慢速。
-
函数
unshift
:它将解开“ a” 一定次javaScript中的unshift表示添加到列表
-
函数
shift
将移动“ a” 一定数量shift用于从列表的开头删除
-
函数
push
将推动“ a” 一定数量的时间。推送方法用于在数组的末尾添加一个或多个元素
-
函数
pop
将弹出“ a” 一定数量。pop方法用于从数组中删除最后一个元素并返回该元素。
-
基于索引的功能
get
。以防万一它是引擎盖下的LinkedList,如果我们要逐步获得更大的索引,我们应该看到线性放缓。 -
函数
push_arr
,pop_arr
,shift_arr
,unshift_arr
是高阶功能,将重复调用push
,pop
,shift
,shift
和unshift
函数。 -
然后进行测试...
测试
现在我们将测试我们的功能,并尝试弄清楚结果指示
pro-tip :每当我们进行 performance 测试时,您应该使用阶梯梯子型方法,以便您可以看到它的成长方式,以便您可以运行线性回归。
const tests = [10, 100, 1000, 10000, 100000, 1_000_000, 10_000_000];
console.log("Testing get");
tests.forEach(t => {
a.length = 0;
push(t);
console.log(t, time(get(t - 1)));
});
console.log("push");
tests.forEach(t => {
a.length = 0;
push(t);
console.log(t, time(push_arr(1000)));
});
console.log("pop");
tests.forEach(t => {
a.length = 0;
push(t);
console.log(t, time(pop_arr(1000)));
});
console.log("unshift");
tests.forEach(t => {
a.length = 0;
push(t);
console.log(t, time(unshift_arr(1000)));
});
console.log("shift");
tests.forEach(t => {
a.length = 0;
push(t);
console.log(t, time(shift_arr(1000)));
});
让我们总结:
-
我们将使用10、100、100 .... 10000000元素进行测试。
-
在第一次测试中,“测试获取”,我们将在值中转到
push
,并为最后一个元素做一个get
此处的论文是,如果索引是线性的,我们应该看到速度放缓,因为数组变得更大
-
在第二次测试中,“推”,我们将在生长到一定长度的
后将其转到t.
push
。如果按下是基于数组中的项目数,我们应该从理论上看到发生的放缓。因此,每个步骤都应该线性地变慢。
-
相同的论文适用于“ pop”,“ shift”和“ unshift”测试。
结果
是时候运行我们的代码并检查结果锅的方式以及在谈论javaScript中的数组
中如何朝哪个方向发展。因为这是打字稿,运行npx ts-node {file-name}.ts
测试获取
阵列的大小无关紧要。这是超级傻瓜。
测试推动
与获得的情况相同,它'很快。
测试流行
类似的结果与 get 和推动,相当快。
测试解开和转移
在这里,我们观察到测试用例的速度非常慢,并且具有线性生长。
所以我们从这些结果中推断出什么:
-
即时访问
-
即时推动并在结尾处弹出
-
线性转移和解散
因此,它是 arraylist
数组列表是类似于数组的数据结构,但是它具有动态大小,可让您更有效地添加和删除元素。数组列表通常用于编程语言中以存储和操纵项目集合。
结论
我们可以安全地得出JavaScript阵列是动态的,实际上是 ArrayLists 在引擎盖下。
学分
感谢您阅读此博客。我希望您发现这些信息有帮助,如果您喜欢它,请考虑与他人分享。
bye!