001 Array 类型

《JavaScript 高级程序设计》这本书被称为 JavaScript 编程的圣经,又称为红宝书。记得这本书是我在刚学前端那会和犀牛书一起购买的,这期间断断续续翻了翻,大部分都处于落灰状态。
这本书很经典,关于 JavaScript 编程的方方面面基本上都讲到了,要是能够通读一遍,可以省去一些翻文档和查资料的时间,这本书的内容也是挺丰盛的,因此我专门建了一个文集,用来做一些读书笔记,以在忘记某块知识时能够回头翻一翻。

判断数组

关于判断数组,这里总结两种方式:
1.使用 Object 原型链上的 toString 方法判断:

function isArray(arr){
    return Object.prototype.toString.call(arr).indexOf("Array") !== -1
}

isArray([]) // true
isArray({}) // false

2.使用 Array 对象上原生的 isArray 方法:

Array.isArray([]) //true
Array.isArray({}) //false

数组的 toString 方法

调用数组的 toString 方法,会依次调用数组每一项的 toString 方法,然后将返回值使用逗号进行拼接:

const arr = [{a:1},[],1,2,"hello"]
arr.toString() // "[object Object],,1,2,hello"

同理,调用数组的 toLocaleStringvalueOf 方法时也会依次调用数组各项元素的 toLocaleStringvalueOf 方法,然后使用逗号进行拼接。
我们也可以修改数组各项元素的 toString 方法,以取代默认结果:

let ele1 = {
    name:"ele1",
    toString(){
        return "么么哒"
    }
}
let ele2 = {
    name:"ele2",
    toString(){
        return "呵呵哒"
    }
}
const arr = [ele1,ele2]

arr.toString() //"么么哒,呵呵哒"

对于数组的 toLocaleStringvalueOf 方法同样适用。

栈/队列方法

我们可以使用数组来模拟栈或者队列数据结构。
栈方法:pushpop

let arr = []
arr.push(1,2)
arr.pop() //2
arr.pop() //1

对列方法:pushshift

let arr = []
arr.push(1,2)
arr.shift() //1
arr.shift() //2

反向队列:unshiftpop

let arr = []
arr.unshift(1,2)
arr.pop() //2
arr.pop() //1

排序方法

1.reverse 方法:
该方法用来对数组进行反转:

let arr = [1,2,3]
arr.reverse() // [3,2,1]

2.sort 方法
该方法用来对数组进行排序,默认按照升序排序,并且在排序时通过元素的 toString 进行位置比较。
因此下面的排序可能不是我们想要的结果:

let arr = [1,2,10,3,20]
arr.sort() //[1,10,2,20,3]

除此之外,sort 方法可以接受一个函数作为参数,用来自定义排序规则。
该参数函数接受两个待比较的元素作为参数,函数返回值决定了这两个元素的排序:

  • 返回值小于 0,升序
  • 返回值大于 0,降序
  • 返回值等于 0,表示这两个参数相等,按照参数顺序排序
let arr = [1,2,10,20,3]
arr.sort((prev,next) => prev - next) // [1, 2, 3, 10, 20]

以上的方法适用于元素的 valueOf 方法返回数值(或者可以隐式转换为数值)的情况,因为只有数值才可以做减法的。如果元素的 valueOf 方法返回的不是数值(或者可以隐式转换为数值),就需要我们手动进行判断,然后进行返回:

let arr = [{val:1},{val:2},{val:10},{val:20},{val:3}]
arr.sort((prev,next) => {
    return prev.val - next.val
}) //  [{val:1},{val:2},{val:3},{val:10},{val:20}]

注意:reversesort 方法都会在原始的数组上进行修改。

操作方法

1.concat 方法
该方法用来进行数组合并,接受的参数如下:

  • 无参数:返回一个当前数组的副本
  • 参数为一个或多个变量、数组:合并当前数组和参数元素,返回合并后的数组

如果参数中含有数组,则会将该数组拆开,并合并到新数组中。

[].concat(1,2,[3,[4,5]]) //[1,2,3,[4,5]]

该方法不会对原始数组进行修改。
2.slice 方法
该方法用来从原始数组中截取一部分元素,基于这些元素再创建一个新数组。
slice 方法的参数:

  • 起始位置:截取数组时的起始位置,可为负数,可选,默认为0
  • 结束位置:截取数组时的结束位置,可为负数,可选,默认为数组的长度

slice 的参数为负数时,该参数和数组长度的和就是实际截取时的启示/结束位置,如果结束位置(经计算转化后)小于起始位置(经计算转化后),则返回一个空数组。

[1,2,3].slice() //[1,2,3]
[1,2,3].slice(1) //[2,3]
[1,2,3].slice(-2,-1) //[2]
[1,2,3].slice(-1,-2) //[]
...

slice 方法不会修改原始数组。
3.splice 方法
该方法较强大,可以用来删除、插入、替换数组元素。该方法会对原始数组进行修改。
1)删除元素
使用 splice 方法删除数组元素需要两个参数:

  • 删除元素的起始位置
  • 删除元素的个数

返回被删除的元素组成的数组。

let arr = [1,2,3]
arr.splice(0,1) //[1]
arr //[2,3]

2)插入元素
使用 splice 方法插入元素需要至少三个参数:

  • 插入的起始位置
  • 0 (表示不删除元素)
  • 插入的元素序列,可为多个

由于没有删除元素,因此调用该方法返回一个空数组

let arr = [1,2,3]
arr.splice(0,0,"memeda","heheda") //[]
arr // ["memeda", "heheda", 1, 2, 3]

3)替换元素
使用 splice 方法替换元素的原理是先删除该元素,在在其位置上进行替换,在替换时可以使用多个元素序列。

let arr = [1,2,3]
arr.splice(1,1,"memeda","heheda") //[2]
arr //[1, "memeda", "heheda", 3]

位置方法

数组中有两个位置方法:indexOflastIndexOf,这两个方法用来查找元素在数组中的位置。indexOf 是从数组开头开始寻找,找到第一个匹配的元素便停止,如果没有匹配到元素,则返回 -1,lastIndexOf 从数组的结尾开始寻找,匹配方式类似。
需要注意的是,indexOflastIndexOf 匹配元素时要求严格相等(===)。
另外,这两个方法还可以接受起始位置和结束位置两个参数(可选),表示搜寻的位置。

let person = {name:"MIKE"}
let arr1 = [{name:"MIKE"}]
let arr2 = [person]
arr1.indexOf(person) //-1
arr2.indexOf(person) //0

由于使用 indexOflastIndexOf 方法匹配元素时要求严格相等,因此 arr1 数组并不能匹配到 person 对象。

迭代方法

数组还有几个迭代方法,用来对数组内部的元素做一些迭代操作,这些方法都接受一个函数作为参数,每次进行迭代时都会执行该函数。该函数的参数为:值、位置、原数组
1.every 方法
该方法用来对数组的每一项进行迭代,如果函数对每一个元素都返回 true,则 every 的返回结果为 true

[1,2,3].every((v)=> v>0) //true
[1,2,3].every((v)=> v>1) //false

2.some 方法
该方法和 every 方法类似,但不要求函数对每一个元素返回 true,只要有一个元素在迭代时返回 truesome 方法就返回 true
true,则 every 的返回结果为 true

[1,2,3].some((v)=> v>0) //true
[1,2,3].some((v)=> v>1) //true

3.filter 方法
该方法用来对数组的每一项进行过滤,返回符合要求的元素列表.

[1,2,3].filter(v=>v%2) //[1,2]

4.forEach 方法
该方法用来对数组的每一项进行操作,该方法没有返回值,也不会影响原始数组,类似于普通的 for 循环。

[1,2,3].forEach(v=>{ console.log(v) }) // 1,2,3

5.map 方法
该方法用来对数组的每一项进行操作,然后将操作的结果映射到一个新数组。

[1,2,3].map(v=>v*2) //[2,4,6]

归并方法

数组还有两个归并方法:reducereduceRight
这两个方法会对数组的每一项进行迭代,然后构建一个最终的返回值。可以接受四个参数:

  • 前一个值
  • 后一个值
  • 当前索引
  • 原数组对象

在迭代的过程中,函数的返回值会作为第一个参数传入下一次的迭代的函数中,并最终返回一个最终值。在第一次进行迭代时,前一个参数和后一个参数分别是数组的第一个元素和第二个元素。
reduceRight 从数组的末尾开始归并,其他和 reduce 一致。

// 对数组的每一项相乘
[1,2,3,4,5].reduce((prev,next) => prev * next) //120
[1,2,3,4,5].reduceRight((prev,next) => prev + next) //15

当涉及到对数组元素的累加、累积等操作时,这两个方法很好用。

完。

你可能感兴趣的:(001 Array 类型)