• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-04-04 20:40 Aet |  隐藏边栏 |   抢沙发 |  16 
文章评分 2 次,平均分 5.0 :

文档

  1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference

数组方法

添加/移除数组元素

  1. arr.push(...items) —— 从尾端添加元素
  2. arr.pop() —— 从尾端提取元素
  3. arr.shift() —— 从首端提取元素
  4. arr.unshift(...items) —— 从首端添加元素

splice

  1. 数组是对象,所以我们可以尝试使用 delete:

  1. 元素被删除了,但数组仍然有 3 个元素,我们可以看到 arr.length == 3
    1. 这很正常,因为 delete obj.key 是通过 key 来移除对应的值
    2. 对于对象来说是可以的。但是对于数组来说,我们通常希望剩下的元素能够移动并占据被释放的位置
  2. splice可以做所有事情:添加,删除和插入元素
    1. 它从索引 start 开始修改 arr:删除 deleteCount 个元素并在当前位置插入 elem1, ..., elemN
    2. 最后返回被删除的元素所组成的数组

  1. 删除了 3 个元素,并用另外两个元素替换它们:

  1. splice 返回了被删除的元素所组成的数组:

  1. 将 deleteCount 设置为 0,splice 方法就能够插入元素而不用删除任何元素:

  1. 允许负向索引

slice

  1. 语法是:
    1. 会返回一个新数组,将所有从索引 start 到 end(不包括 end)的数组项复制到一个新的数组
    2. start 和 end 都可以是负数,在这种情况下,从末尾计算索引

  1. 也可以不带参数地调用它:arr.slice() 会创建一个 arr 的副本

concat

  1. 创建一个新数组,其中包含来自于其他数组和其他项的值
  2. 它接受任意数量的参数 —— 数组或值都可以
  3. 结果是一个包含来自于 arr,然后是 arg1,arg2 的元素的新数组

  1. 通常,它只复制数组中的元素。其他对象,即使它们看起来像数组一样,但仍然会被作为一个整体添加:

  1. 如果类数组对象具有 Symbol.isConcatSpreadable 属性,那么它就会被 concat 当作一个数组来处理:此对象中的元素将被添加:

遍历:forEach

  1. 允许为数组的每个元素都运行一个函数

  1. 显示了数组的每个元素:

  1. 介绍了它们在目标数组中的位置:

indexOf/lastIndexOf 和 includes

  1. arr.indexOf(item, from) —— 从索引 from 开始搜索 item,如果找到则返回索引,否则返回 -1
  2. arr.includes(item, from) —— 从索引 from 开始搜索 item,如果找到则返回 true(译注:如果没找到,则返回 false)

  1. 注意,indexOf 和 includes 使用严格相等 === 进行比较
    1. 所以,如果我们搜索 false,它会准确找到 false 而不是数字 0
  2. 方法 arr.lastIndexOf与 indexOf 相同,但从右向左查找

  1. 方法 includes 可以正确的处理 NaN
    1. 方法 includes 的一个次要但值得注意的特性是,它可以正确处理 NaN,这与 indexOf 不同:
    2. 这是因为 includes 是在比较晚的时候才被添加到 JavaScript 中的,并且在内部使用了更新了的比较算法

find 和 findIndex/findLastIndex

  1. 语法
    1. 有一个对象数组。我们如何找到具有特定条件的对象?

  1. 例如,我们有一个存储用户的数组,每个用户都有 id 和 name 字段。让我们找到 id == 1 的那个用户:

  1. arr.findIndex方法(与 arr.find)具有相同的语法,但它返回找到的元素的索引,而不是元素本身。如果没找到,则返回 -1
  2. arr.findLastIndex方法类似于 findIndex,但从右向左搜索,类似于 lastIndexOf

filter

  1. find 方法搜索的是使函数返回 true 的第一个(单个)元素
  2. 如果需要匹配的有很多,我们可以使用 arr.filter(fn)
    1. 语法与 find 大致相同,但是 filter 返回的是所有匹配元素组成的数组:

转换数组:map

  1. arr.map方法是最有用和经常使用的方法之一
  2. 它对数组的每个元素都调用函数,并返回结果数组

重新排序:sort(fn)

  1. arr.sort方法对数组进行 原位(in-place) 排序,更改元素的顺序
    1. 原位是指在此数组内,而非生成一个新数组
  2. 它还返回排序后的数组,但是返回值通常会被忽略,因为修改了 arr 本身\
  3. 示例:
    1. 这些元素默认情况下被按字符串进行排序
    2. 从字面上看,所有元素都被转换为字符串,然后进行比较

  1. 要使用我们自己的排序顺序,我们需要提供一个函数作为 arr.sort() 的参数

  1. 使用 localeCompare for strings

颠倒顺序:reverse

  1. 用于颠倒 arr 中元素的顺序
    1. 它也会返回颠倒后的数组 arr

split

  1. 用“逗号后跟着一个空格”作为分隔符:

  1. split 方法有一个可选的第二个数字参数 —— 对数组长度的限制。如果提供了,那么额外的元素会被忽略
    1. 但实际上它很少使用:

  1. 调用带有空参数 s 的 split(s),会将字符串拆分为字母数组:

join

  1. arr.join(glue)与 split 相反
    1. 它会在它们之间创建一串由 glue 粘合的 arr 项

reduce和reduceRight

  1. 当我们需要遍历一个数组时 —— 我们可以使用 forEach,for 或 for..of
  2. 当我们需要遍历并返回每个元素的数据时 —— 我们可以使用 map
  3. arr.reduce方法和 arr.reduceRight方法和上面的种类差不多,但稍微复杂一点
    1. 它们用于根据数组计算单个值
    2. accumulator —— 是上一个函数调用的结果,第一次等于 initial(如果提供了 initial 的话)
    3. item —— 当前的数组元素
    4. index —— 当前索引
    5. arr —— 数组本身

  1. 通过一行代码得到一个数组的总和:
    1. 也可以省略初始值:
    2. 如果没有初始值,那么 reduce 会将数组的第一个元素作为初始值,并从第二个元素开始迭代

  1. 建议始终指定初始值

Array.isArray

  1. 数组是基于对象的,不构成单独的语言类型
    1. 所以 typeof 不能帮助从数组中区分出普通对象:

  1. 但是数组经常被使用,因此有一种特殊的方法用于判断:Array.isArray(value)
    1. 如果 value 是一个数组,则返回 true;否则返回 false

大多数方法都支持 “thisArg”

  1. 几乎所有调用函数的数组方法 —— 比如 find,filter,map,除了 sort 是一个特例,都接受一个可选的附加参数 thisArg
    1. 上面的部分中没有解释该参数,因为该参数很少使用

  1. thisArg 参数的值在 func 中变为 this
    1. 例如,在这里我们使用 army 对象方法作为过滤器,thisArg 用于传递上下文(passes the context):

Iterable object(可迭代对象)

概述

  1. 可迭代(Iterable) 对象是数组的泛化
    1. 这个概念是说任何对象都可以被定制为可在 for..of 循环中使用的对象
  2. 数组是可迭代的
    1. 但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的

Symbol.iterator

  1. 例如,我们有一个对象,它并不是数组,但是看上去很适合使用 for..of 循环

  1. 为了让 range 对象可迭代(也就让 for..of 可以运行)我们需要为对象添加一个名为 Symbol.iterator 的方法(一个专门用于使对象可迭代的内建 symbol)
    1. 当 for..of 循环启动时,它会调用这个方法(如果没找到,就会报错)
      这个方法必须返回一个 迭代器(iterator) —— 一个有 next 方法的对象
    2. 从此开始,for..of 仅适用于这个被返回的对象
    3. 当 for..of 循环希望取得下一个数值,它就调用这个对象的 next() 方法
    4. next() 方法返回的结果的格式必须是 {done: Boolean, value: any},当 done=true 时,表示循环结束,否则 value 是下一个值

  1. 注意可迭代对象的核心功能:关注点分离
    1. range 自身没有 next() 方法
    2. 相反,是通过调用 range[Symbol.iterator]() 创建了另一个对象,即所谓的“迭代器”对象,并且它的 next 会为迭代生成值
    3. 因此,迭代器对象和与其进行迭代的对象是分开的
  2. 从技术上说,我们可以将它们合并,并使用 range 自身作为迭代器来简化代码
    1. 现在 range[Symbol.iterator]() 返回的是 range 对象自身:它包括了必需的 next() 方法,并通过 this.current 记忆了当前的迭代进程
    2. 这样更短,对吗?是的。有时这样也可以
    3. 但缺点是,现在不可能同时在对象上运行两个 for..of 循环了:它们将共享迭代状态,因为只有一个迭代器,即对象本身
      但是两个并行的 for..of 是很罕见的,即使在异步情况下

字符串是可迭代的

  1. 数组和字符串是使用最广泛的内建可迭代对象
  2. 对于一个字符串,for..of 遍历它的每个字符:

  1. 对于代理对(surrogate pairs),它也能正常工作
    1. 译注:这里的代理对也就指的是 UTF-16 的扩展字符

显式调用迭代器

  1. 采用与 for..of 完全相同的方式遍历字符串,但使用的是直接调用
    1. 这段代码创建了一个字符串迭代器,并“手动”从中获取值
    2. 很少需要我们这样做,但是比 for..of 给了我们更多的控制权

可迭代(iterable)和类数组(array-like)

  1. Iterable 如上所述,是实现了 Symbol.iterator 方法的对象
  2. Array-like 是有索引和 length 属性的对象,所以它们看起来很像数组
  3. 当我们将 JavaScript 用于编写在浏览器或任何其他环境中的实际任务时,我们可能会遇到可迭代对象或类数组对象,或两者兼有
    1. 例如,字符串即是可迭代的(for..of 对它们有效),又是类数组的(它们有数值索引和 length 属性)
  4. 但是一个可迭代对象也许不是类数组对象。反之亦然,类数组对象可能不可迭代
    1. 例如,上面例子中的 range 是可迭代的,但并非类数组对象,因为它没有索引属性,也没有 length 属性
    2. 下面这个对象则是类数组的,但是不可迭代:

  1. 可迭代对象和类数组对象通常都 不是数组,它们没有 push 和 pop 等方法

Array.from

  1. 可以接受一个可迭代或类数组的值,并从中获取一个“真正的"数组"
    1. 就可以对其调用数组方法了
    2. 在 (*) 行的 Array.from 方法接受对象,检查它是一个可迭代对象或类数组对象,然后创建一个新数组,并将该对象的所有元素复制到这个新数组

  1. 如果是可迭代对象,也是同样:

  1. Array.from 的完整语法允许我们提供一个可选的“映射(mapping)”函数:
    1. 可选的第二个参数 mapFn 可以是一个函数,该函数会在对象中的元素被添加到数组前,被应用于每个元素,此外 thisArg 允许我们为该函数设置 this

  1. 用 Array.from 将一个字符串转换为单个字符的数组:
    1. 与 str.split 方法不同,它依赖于字符串的可迭代特性
    2. 因此,就像 for..of 一样,可以正确地处理代理对(surrogate pair)

  1. 甚至可以基于 Array.from 创建代理感知(surrogate-aware)的slice 方法
    1. 也就是能够处理 UTF-16 扩展字符的 slice 方法

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享
繁