17前端成长日记-Array 对象

294 阅读7分钟

什么是数组

ArrayJavaScript 的原生对象,同时也是一个构造函数,用它可以生成新的数组。

var a = new Array(2)
a.length //2

Array(3) 和 new Array(3)在表达形式上没有区别

只给 Array() 传一个参数时,这个参数代表数组的 length

静态方法

1. Array.isArray()

Array.isArray 方法可以判断传入的参数是否是一个数组

var a = [1,2,3]
Array.isArray(a) //true

2.Array.from()

Array.from 方法从一个类数组或可迭代对象创建一个新的数组实例

var arr = [1,2,3]
var arr2 = Array.from(arr) // [1,2,3]

Array.from 方法还可以接收一个回调函数,可以实现map方法的效果

var arr = [1,2,3]
var arr2 = Array.from(arr,item=>item+1) // [2,3,4]

实例方法

1. push()

push方法可以在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度

var a = [1,2,3]
a.push(4,5) //4
a // [1,2,3,4,5]

2. unshift()

unshift 方法可以在数组的头部添加一个或多个元素,并返回添加新元素后的数组长度

var a = [2,3]
a.unshift() //3
a // [1,2,3]

1. pop()

pop方法可以删除数组末端的一个元素,并返回该元素

var a = [1,2,3]
a.pop() //3
a //[1,2]

2. shift()

shift 方法可以删除数组的第一个元素,并返回该元素

var a = [1,2,3]
a.shift() //1
a //[2,3]

3. delete()

Array 也属于对象,所以也可以用 delete 方法删除,并返回一个布尔值,true 表示删除成功

用 delete 删除会在数组中留下一个空洞

var a = [1,2,3]
delete a[1]
a //[empty,1,3]
a.length //3

4. fill()

fill 方法用来填充数组中从起始索引到终止索引内的全部元素,不包括终止索引,它会修改原数组 fill(value,start,end) 接受三个参数 value 需要填充数组的值,start 起始索引,end 终止索引

var arr = [1,2,3,4]

// 将数组内的每一项全部替换成1
arr.fill(1) // [1,1,1,1]
var arr = [1,2,4,4,5]

// 将 2 后面的 4 填充为 3
arr.fill(3,2,3)

1. 直接改

let a = [1,2,3]
a[0] = 0
a //[0,2,3]

2. splice()

splice 方法可用于向数组指定位置添加新项

splice(添加新元素的位置,要删除几个元素,你要添加的元素)

划重点 splice 方法不仅可实现 pop shift push unshift 一样的效果,还可以在任意位置删除添加

let a = [1,2,3,1,7,8]
// 删除 3后面的1再添加4,5,6
a.splice(3,1,4,5,6)
a //[1, 2, 3, 4, 5, 6, 7, 8]

在头部添加新元素

let a = [4,5]
a.splice(0,0,1,2,3,)
a // [1, 2, 3, 4, 5]

在末尾添加新元素

let a = [1,2]
a.splice(a.length,0,3,4,5)
a // [1, 2, 3, 4, 5]

删除第一个元素

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

删除末尾元素

let a = [1,2,3]
a.splice(a.length-1,1)
a //[1,2]

2 slice

slice 方法可以截取数组中的一段元素,生成一个新数组

slice(开始位置,结束位置)

let a = [1,2,3,4,5]
let b = a.slice(2)
a //[1,2,3,4,5]
b //[3,4,5]
b = a.slice(2,4)
b // [3,4]

3. sort()

sort() 对数组按照Unicode编码进行排序

var a = [3,1,2]

a.sort() //默认从大到小排列
//[1,2,3]

a.sort(function(x,y){
    return y - x // 如果返回值大于 0 则交换位置
})
//[3,2,1]

//按得分成绩进行排序
var students = ['小明','小红','小花']
var scores = { 小明: 59, 小红: 99, 小花: 80 }

students.sort(function(x,y){
    return scores[y] - scores[x]
})
// ["小红", "小花", "小明"]

4. reverse()

reverse() 可翻转排列数组

var a = [1,2,3]

a.reverse()
//[3,2,1]

5. join()

join() 数组内的值连起来,返回一个字符串

var a = [1,2,3]

a.join() //默认是用','连接
//"1,2,3"

a.join('+')
//"1+2+3"

6. concat()

concat() 合并多个数组,并返回一个新数组

var a = [1,2,3]
var b = [4,5,6]

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

//concat([])可复制数组
var b = a.concat([])
//[1,2,3]

位置方法

2. indexOf()、lastIndexOf()

indexOf 方法可以返回元素在数组中第一次出现的位置,如果没有就返回 -1

var a = ['a','b','c']
a.indexOf('a') // 0
a.indexOf('d') //-1

lastIndexOf 方法可以返回元素最后一次在数组中出现的位置

var a = ['a','b','c','a']
a.lastIndexOf('a') // 3

可以通过判断 indexOf() 是否等于 lastIndexOf 来判断元素有没有多次出现在数组里

以下是通过 indexOf() 未数组去重的例子

let array = ['a','a','b','a','b','c','b','c']
let newArray = []

let unique = () => {
  for (let i = 0; i < array.length; i++) {
    if (newArray.indexOf( array[i] ) === -1) {
      newArray.push(array[i])
    }
  }
  return newArray
}

unique() //["a", "b", "c"]

6. find() findIndex()

ES6 扩展语法

  • find 方法用于找出第一个符合条件的数组成员,如果所有成员都不符合条件,则返回 undefined
  • 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
let arr = [1,2,3,4,5,6]

arr.find((value,index) => value > 4) //5

arr.findIndex((value,index) => value > 4) // 4

7. includes()

includes() 方法可以判断一个元素是否在数组内,如果不在返回false

var arr = [1,2,3,4,5]

arr.includes(1) // true
arr.includes(6) // false

迭代方法

1. forEach()

forEach()遍历数组获取数组的key和value,它参数是一个函数

如果 value 重复,只返回一个

var a = [1,2,3]

a.forEach(function (value,key){
    console.log('value:',value,'key:',key)
})
// value: 1 key: 0
// value: 2 key: 1
// value: 3 key: 2
var a = [1,2,3,4,1]
a.forEach(function(value){
    console.log(value)
})
//1
//2
//3
//4

自己实现一个 forEach

Array.prototype.myForEach(fn,context){
    // 拷贝数组
    let arr = Array.prototype.slice.call(this)
    for(let i =0; i < arr.length; i++){
       fn.call(context,arr[i],i,this)
    }
}

2. map()

map() 将数组的所有成员依次传入参数函数,并把每一次的结果组成一个新的数组返回

map() 第一个参数是一个函数,他接收的第一个参数是数组的当前成员,第二个参数是当前位置,第三个参数是数组本身 map() 第二个参数是其内部函数的 this 指向

//得到所有数的2倍数
var a = [1,2,3]

a.map(function(value,key){
    return value*2
})
//[2,4,6]
var arr = ['a', 'b', 'c'];

[1, 2].map(function (e) {
  return this[e];
}, arr)
// ['b', 'c']

自己实现一个map

Array.prototype.myMap(fn,context){
    // 拷贝数组
    let arr = Array.prototype.slice.call(this)
    let mappeArr = []
    for(let i =0; i < arr.length; i++){
        mappeArr.push(fn.call(context,arr[i],i,this))
    }
    return mappeArr
}

3. reduce()

reduce() 方法依次处理数组的每个成员,最终累计为一个值 reduce()的第一个参数是一个函数,这个函数的的第一个参数为上一轮的返回值,默认为数组的第一个元素(初始值一个由reduce的第二个参数修改),第二个参数会从数组的第一个元素开始遍历(如果定义了reduce的第二个参数,就会从数组的第一个参数开始

var a = [1,2,3]

a.reduce(function(a,b){
    console.log(a,b)
    return a + b
})
// 1 2
// 3 3
// 6

a.reduce(function(a,b){
    console.log(a,b)
    return  a + b
},10)
// 10 1
// 11 2
// 13 3
// 16


//用reduce 表示 map
a.reduce(function(arr,n){
    arr.push(n*2)
    return arr
},[])
//[2,4,6]

//用reduce 表示 filter
a.reduce(function(arr,n){
    if(n % 2 === 0){
        arr.push(n)
    }
    return arr
},[])

自己实现以个 reduce

Array.prototype.myReduce = function(fn.initalValue){
    let arr = Array.prototype.slice.call(this)
    let res,startIndex
    res = initalValue ? initalValue : arr[0]
    startIndex = initalValue? 0:1
    for(let i = startIndex; i<arr.length; i++){
        res = fn.call(null,res,arr[i],i,this)
    }
    return res 
}

4. filter()

filter() 过滤数组

//获得所有偶数

var a = [1,2,3,4,5,6,7,8,9]

a.filter(function(value,key){
    return value % 2 === 0
})
//[2, 4, 6, 8]

5.some()

some()对数组中的每一项运行指定函数,如果函数对任意一项返回true,则返回 true

var arr = [1,2,3,4,5]

arr.some((item)=>(item===2)) // true
arr.some((item)=>(item===6)) // false

6. every()

every() 对数组中的每一项运行指定函数,如果函数对每一项都返回true,则返回 true

var arr = [1,2,3,4,5]

arr.every((item)=>(item>0)) // true
arr.every((item)=>(item>1)) // false

判断数组为空

let arr = []

+arr === 0 // true

arr.length === 0 // true

JSON.stringify(arr) === '[]' // true

数组降维

还可以将数组转换成字符串再利用字符串的 split 方法转换成数组

二维数组

let arr = [[1],[2],[3,4,5]]

arr = Array.prototype.concat.apply([],arr) // [1, 2, 3,4,5]

多维数组

let arr = [[1],[[2]],[3,[4]],[5]]

arr = arr.flat(4) //[1, 2, 3,4,5]
function flat(arr){
	var newArr = []
	function temp(arr){
		arr.forEach((item)=>{
		if(Array.isArray(item)){
			temp(item)
		}else{
			newArr.push(item)
		}
	})
	}
	temp(arr)
	return newArr 
}
while (arr.some(Array.isArray)) {
  arr = [].concat(...arr);
}