JavaScript之数组方法(1.0)

在前端开发过程中,用到最多的就是数组和对象的操作方法,这个无论任何框架,都需要对数据进行操作的,所以就整体再复习一下数组和对象的方法。

1.Array.from

Array.from() 静态方法用于从可迭代对象或类数组对象创建一个新的浅拷贝数组实例。以下是该方法的一些关键点和示例:

语法

Array.from(arrayLike[, mapFn[, thisArg]])

参数

  • arrayLike:一个可迭代对象或类数组对象,用于转换成数组。

  • mapFn(可选):一个映射函数,将在数组的每个元素上调用。

  • thisArg(可选):执行 mapFn 时使用的 this 值。

示例

基本用法

const arrayLike = {0: 'a', 1: 'b', 2: 'c', length: 3};

const arr = Array.from(arrayLike);

console.log(arr); // 输出: ['a', 'b', 'c']

使用映射函数

const arrayLike = {0: 'a', 1: 'b', 2: 'c', length: 3};

const arr = Array.from(arrayLike, (element) => element.toUpperCase());

console.log(arr); // 输出: ['A', 'B', 'C']

 

然后列举一下其他用法 

转换 Set

const set = new Set([1, 2, 3]);

const arr = Array.from(set);

console.log(arr); // 输出: [1, 2, 3]

转换 arguments 对象

function getArgs() {

return Array.from(arguments);

}

const arr = getArgs('a', 'b', 'c');

console.log(arr); // 输出: ['a', 'b', 'c']

使用场景

  • 将类数组对象转换为数组:这对于处理 DOM 集合、arguments 对象和其他类数组结构特别有用。

  • 从可迭代对象创建数组:您可以轻松地将 Set、Map 和其他可迭代对象转换为数组。

  • 在转换过程中应用变换:通过提供映射函数,您可以在转换过程中对每个元素进行操作。

性能考虑

  • 浅拷贝:Array.from() 执行的是浅拷贝,这意味着嵌套对象不会被深度克隆。

  • 性能:对于大型数据集,要考虑创建新数组和应用变换的性能影响。

结论

Array.from() 是一个多功能的方法,简化了将各种类型的对象转换为数组的过程。它特别适用于处理类数组对象和可迭代对象,并且可以通过映射函数扩展以执行额外的变换。

2.Array.fromAsync

Array.fromAsync() 静态方法从异步可迭代对象、可迭代对象或类数组对象创建一个新的浅拷贝数组实例。

这里额外解释一下这段代码中的 * 号和 yield 关键字的含义。

异步生成器函数

在这段代码中,async function* 定义了一个异步生成器函数。让我们逐步解析:

1. async function* 语法
  • async function* 是定义异步生成器函数的关键字组合。
  • async 表示这是一个异步函数,可以使用 await 关键字。
  • function* 表示这是一个生成器函数,可以使用 yield 关键字。
2. 生成器函数

生成器函数是一种特殊的函数,可以暂停和恢复其执行,并生成一系列值。生成器函数通过 yield 关键字来生成值,并通过 yield 暂停执行。

3. 异步生成器函数

异步生成器函数结合了生成器函数和异步函数的特点,可以生成异步值。异步生成器函数中的 yield 可以生成 Promise,并且在每次 yield 后,生成器会暂停执行,直到 Promise 被解决。

 解释一下那个yield关键字,它在这里每次循环生成一个值i,并在生成值之前暂停执行一段时间,直到下一次调用生成器的next方法。

function* simpleGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = simpleGenerator();

console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

在这里附上上面实例代码的执行结果,因为是异步的,所以它的执行顺序相对于其他同步代码在最后执行。

 3.Array.isArray

这个方法比较简单,就是判断你传递过去的参数是否为数组,然后返回布尔值,是就是true,不是就是false。

4.Array.of

 

 执行结果:

 5.Array.prototype.at

这里其实不用区分是不是实例方法,还是静态方法啥的,使用的时候也不用纠结这些,知道,会用既可以了。

这里列举出CDN上的四种方法,它分成了四类,要不是去CDN上查一下文档,我还不知道还有两种方法呢,长见识了,不过,剩下的两种的稀有程度能用到说明你的开发经验也足够了,这样就无脑官网,其他技术论坛博客啥的都是浮云。

回到正题,介绍一下这个方法:

  

 

这里索引大家应该都知道,数组的索引,准确来说,任何用到索引的语言,都是以0开始【第一个元素】,如果出现负数的索引,那么就是-1开始,也就是最后一个元素。 

混入一个slice方法

6.Array.prototype.slice

Array 实例的 slice 方法返回从 start 到 end(不包括 end)索引范围内的数组部分的浅拷贝,形成一个新的数组对象。原始数组不会被修改。

语法

array.slice(start, end)

  • array:调用 slice 方法的数组。
  • start(可选):开始提取的索引位置。如果为负数,则从数组末尾开始计算。
  • end(可选):停止提取的索引位置(不包括该位置)。如果为负数,则从数组末尾开始计算。如果省略,则提取到数组末尾。
返回值
  • 新数组:包含从 start 到 end(不包括 end)索引范围内的元素的新数组。
特点
  • 不改变原数组slice 方法不会修改调用它的数组,而是返回一个新的数组。
  • 支持负索引start 和 end 参数可以是负数,表示从数组末尾开始计算索引。
  • 浅拷贝:返回的新数组是原数组的浅拷贝,即只复制一层深度的对象引用。

示例

基本用法

const array = [1, 2, 3, 4, 5];

const slicedArray = array.slice(1, 3);

console.log(slicedArray); // 输出: [2, 3]

console.log(array); // 输出: [1, 2, 3, 4, 5],原数组未改变

负索引

const array = [1, 2, 3, 4, 5];

const slicedArray = array.slice(-4, -2);

console.log(slicedArray); // 输出: [2, 3]

省略 end 参数

const array = [1, 2, 3, 4, 5];

const slicedArray = array.slice(2);

console.log(slicedArray); // 输出: [3, 4, 5]

浅拷贝

const array = [{ a: 1 }, { b: 2 }];

const slicedArray = array.slice(0, 1);

slicedArray[0].a = 10;

console.log(array); // 输出: [{ a: 10 }, { b: 2 }]

console.log(slicedArray); // 输出: [{ a: 10 }]

总结

  • slice 方法:返回从 start 到 end(不包括 end)索引范围内的数组部分的浅拷贝,形成一个新的数组对象。
  • 不改变原数组slice 方法不会修改调用它的数组,而是返回一个新的数组。
  • 支持负索引start 和 end 参数可以是负数,表示从数组末尾开始计算索引。
  • 浅拷贝:返回的新数组是原数组的浅拷贝,即只复制一层深度的对象引用。

7.Array.prototype.concat()

Array 实例的 concat 方法用于合并两个或多个数组。这个方法不会改变现有的数组,而是返回一个新的数组。

语法

array.concat(value1, value2, ..., valueN)

  • array:调用 concat 方法的数组。
  • value1, value2, ..., valueN:要合并到原数组中的一个或多个数组或值。
参数
  • value1, value2, ..., valueN:可以是数组或其他值。这些参数将被合并到新的数组中。
返回值
  • 新数组:包含所有传入数组或值的新数组。
特点
  • 不改变原数组concat 方法不会修改调用它的数组,而是返回一个新的数组。
  • 可以合并多个数组:可以传入多个数组或值作为参数,所有这些参数都会被合并到新的数组中。
  • 可以传入非数组值:除了数组,还可以传入其他类型的值,这些值会被当作单独的元素添加到新数组中。
  • 浅拷贝:返回的新数组是原数组的浅拷贝,即只复制一层深度的对象引用。

示例

合并两个数组

const array1 = [1, 2, 3];

const array2 = [4, 5, 6];

const result = array1.concat(array2);

console.log(result); // 输出: [1, 2, 3, 4, 5, 6]

console.log(array1); // 输出: [1, 2, 3],原数组未改变

合并多个数组

const array1 = [1, 2, 3];

const array2 = [4, 5, 6];

const array3 = [7, 8, 9];

const result = array1.concat(array2, array3);

console.log(result); // 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]

console.log(array1); // 输出: [1, 2, 3],原数组未改变

合并数组和非数组值

const array1 = [1, 2, 3];

const result = array1.concat(4, [5, 6], 7);

console.log(result); // 输出: [1, 2, 3, 4, 5, 6, 7]

console.log(array1); // 输出: [1, 2, 3],原数组未改变

省略参数

const array1 = [1, 2, 3];

const result = array1.concat();

console.log(result); // 输出: [1, 2, 3],返回原数组的浅拷贝

console.log(array1); // 输出: [1, 2, 3],原数组未改变

总结

  • concat 方法:用于合并两个或多个数组。
  • 不改变原数组concat 方法不会修改调用它的数组,而是返回一个新的数组。
  • 可以合并多个数组:可以传入多个数组或值作为参数,所有这些参数都会被合并到新的数组中。
  • 可以传入非数组值:除了数组,还可以传入其他类型的值,这些值会被当作单独的元素添加到新数组中。
  • 浅拷贝:返回的新数组是原数组的浅拷贝,即只复制一层深度的对象引用。

 8.Array.prototype.copyWithin

Array 实例的 copyWithin 方法将数组的一部分浅拷贝到同一数组的另一个位置,并返回该数组而不改变其长度。

语法

array.copyWithin(target, start = 0, end = this.length)

  • array:调用 copyWithin 方法的数组。
  • target:开始复制的目标索引位置。
  • start(可选):开始复制的起始索引位置,默认为 0
  • end(可选):停止复制的结束索引位置(不包括该位置),默认为数组的长度。
参数
  • target:必需。开始复制的目标索引位置。如果为负数,则从数组末尾开始计算。
  • start(可选):开始复制的起始索引位置。如果为负数,则从数组末尾开始计算。默认为 0
  • end(可选):停止复制的结束索引位置(不包括该位置)。如果为负数,则从数组末尾开始计算。默认为数组的长度。
返回值
  • 当前数组:返回调用 copyWithin 方法的数组,其中指定的部分已被浅拷贝到目标位置。
特点
  • 不改变数组长度copyWithin 方法不会改变数组的长度,只是移动数组中的元素。
  • 浅拷贝:返回的新数组是原数组的浅拷贝,即只复制一层深度的对象引用。
  • 覆盖原有元素:目标位置的元素会被覆盖。

示例

基本用法

const array = [1, 2, 3, 4, 5];

const result = array.copyWithin(0, 3, 4);

console.log(result); // 输出: [4, 2, 3, 4, 5]

console.log(array); // 输出: [4, 2, 3, 4, 5],原数组已改变

这里第二个参数就是复制的起点位置,如果是3的话,那么索引为3,就是第四个位置的4.

第三个参数就是复制的终点位置,默认就是数组的长度,这里手动设置为5也是一样的效果,设置为5,但是不包括5,就是到索引4,也就是数字5,那么复制的部分就是4,和5,那么就再放到数组开始的位置,那么就是4,5,3,4,5了,如果你把第一个参数设置为1 ,那么就是1,4,5,4,5,决定你最后放到原数组中的位置。

使用负索引

const array = [1, 2, 3, 4, 5]; const result = array.copyWithin(-2, -3, -1); console.log(result); // 输出: [1, 2, 3, 3, 4] console.log(array); // 输出: [1, 2, 3, 3, 4],原数组已改变

默认参数

const array = [1, 2, 3, 4, 5];

const result = array.copyWithin(0);

console.log(result); // 输出: [1, 2, 3, 4, 5]

console.log(array); // 输出: [1, 2, 3, 4, 5],原数组已改变

覆盖原有元素

const array = [1, 2, 3, 4, 5];

const result = array.copyWithin(1, 3, 5);

console.log(result); // 输出: [1, 4, 5, 4, 5]

console.log(array); // 输出: [1, 4, 5, 4, 5],原数组已改变

总结

  • copyWithin 方法:将数组的一部分浅拷贝到同一数组的另一个位置,并返回该数组而不改变其长度。
  • 不改变数组长度copyWithin 方法不会改变数组的长度,只是移动数组中的元素。
  • 浅拷贝:返回的新数组是原数组的浅拷贝,即只复制一层深度的对象引用。
  • 覆盖原有元素:目标位置的元素会被覆盖。

所谓静态方法,就是需要使用Array这样的方式,进行方法的调用,就是Array.of()的形式,如果是原型上的实例方法,我们的使用方式就简单了,如果一个arr=[],这样的形式,就是数组Array的实例,可以直接用arr.pop(),arr.push()这样的方式来使用,而不用使用Array.prototype.pop()这样的方式。

这里额外扩展一下,当然,一个是数组实例,一个是数组原型,我也想验证一下他们两个是否相等,我虽然知道它们不相等,但是不知道原因。因此探究一下arr==Array.prototype,答案如下:

在JavaScript中,arr.pop() 和 Array.prototype.pop() 调用的是同一个方法,但它们是在不同的上下文中被调用的。arr.pop() 是在 arr 这个数组实例的上下文中调用的,而 Array.prototype.pop() 则是直接引用原型上的方法(通常你不会这样直接调用它,除非是为了某些特殊目的,比如方法借用)。arr.pop() 最终是通过原型链调用了 Array.prototype.pop(),但 arr 本身并不等于 Array.prototype。这是因为 arr 是一个具体的数组实例,它包含自己的元素和数据,而 Array.prototype 是一个原型对象,用于定义所有数组实例共享的方法和属性。

当你执行 arr == Array.prototype 时,这个比较是基于引用比较,而不是基于它们是否具有相同的方法或属性。arr 和 Array.prototype 是两个完全不同的对象,它们在内存中的位置(即它们的引用)是不同的。因此,这个比较的结果为 false

相同的情况:

  1. 与数组实例的原型比较

    • 每一个数组实例都有一个指向 Array.prototype 的内部链接(通常称为 [[Prototype]])。虽然无法直接访问这个链接,但可以通过 Object.getPrototypeOf() 方法来获取一个对象的原型。因此,Object.getPrototypeOf(arr) === Array.prototype 对于任何数组实例 arr 来说,结果都是 true
  2. 与其他原型或对象比较

    • Array.prototype 与其他任何原型(如 Object.prototypeFunction.prototype 等)或普通对象(非数组实例)比较,结果都是 false。这是因为它们是不同的对象,即使它们可能共享某些方法或属性。

其实,常用的就那十几个,其他的比较少用的知道就行,用法也比较简单,实在忘了的话去查文档也来得及,不过,常用的数组和对象方法需要牢记,因为这些方法十分常用,要不然有些业务场景你不知道改用哪个数组过对象方法对数据进行处理就很麻烦了。比如reduce这个方法,直到以后就不用使用for循环对数据进行累加处理了。

未完待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mez_Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值