javascript进阶知识5-数组的创建修改

182 阅读8分钟

1.创建数组

使用构造函数:

let arr = new Array();     //[]
let colors = new Array(20);   //[]   length为20
let numbers = new Array(10,20,30);  //[10,20,30]

使用字面量:

let colors = ['red','blue','green']  //创建一个包含3元素的数组
let values = [1,2,];                 //创建一个包含两个元素的数组
let names = [];                      //创建一个空数组

使用Array.from()和Array.of():

ES6新增的用于创建数组的静态方法:from()of()from()用于将类数组结构转换为数组实例,而of()用于将一组参数转换为数组。

类数组就是任何可迭代的结构,或者有一个length属性和可索引元素的结构。类数组可以返回length,但是不能使用数组的方法。

假如页面中有多个div
let div = document.querySelectorAll('div');   //这里得到的就是类数组
let arr = Array.from(div)

console.log(Array.from("Matt"))  //["M","a","t","t"]

Array.of()可以吧一组参数转换为数组。(感觉现在已经没啥用了,因为有解构赋值...)

console.log(Array.of(1,2,3,4))  //[1,2,3,4]
console.log(Array.of(undefined)) //[undefined]

使用解构赋值:

let [...name] = '2323'
console.log(name);  //  ['2', '3', '2', '3']

使用split()函数:

let str = 'my name is ly';
let arr = str.split(' ');
console.log(arr); //[ 'my', 'name', 'is', 'ly' ]

使用对象的Object.getOwnPropertyNames()

Object.getOwnPropertyNames()方法可以列出对象所有的实例属性,无论是否可以枚举。该方法接收一个参数,即对象名。返回的是一个数组,数组包含的是对象的属性名。(关于对象的内容以后再详细总结)

let obj = {
    name: 'leiyan',
    age: 18,
    sayName() {
        console.log(this.name)
    }
}
let keys = Object.getOwnPropertyNames(obj);
console.log(keys); //[ 'name', 'age', 'sayName' ]

使用对象的Object.keys()和Object.values()和Object.entries()

Object.keys()方法获得的是对象上所有可枚举的实例属性。这个方法接收一个对象作为参数,返回包含该对象所有可枚举属性名称的字符串数组。

let obj = {
    name: 'leiyan',
    age: 18,
    sayName() {
        console.log(this.name)
    }
}
let keys = Object.keys(obj);
console.log(keys); //[ 'name', 'age', 'sayName' ]

该方法和Object.getOwnPropertyNames()的区别是Object.getOwnPropertyNames()可以返回不可枚举的属性。(关于枚举后面到对象再说明..)

Object.values()方法返回对象值的数组。

let obj = {
    name: 'leiyan',
    age: 18,
    sayName() {
        console.log(this.name)
    }
}
let keys = Object.values(obj);
console.log(keys); //[ 'leiyan', 18, [Function: sayName] ]

Object.entries()方法返回键值对的数组。

let obj = {
    name: 'leiyan',
    age: 18,
    sayName() {
        console.log(this.name)
    }
}
let keys = Object.entries(obj);
console.log(keys);
//结果    [
//          [ 'name', 'leiyan' ],
//          [ 'age', 18 ],
//          [ 'sayName', [Function: sayName] ]
//        ]

除此之外,Object.keys()和Object.values()、Object.entries()还可以作用于数组,返回结果也是数组。(等下介绍)

此外,上一章正则的match、exec返回的也是数组。

2.复制和填充方法(fill和copyWithin)

ES6新增了两个方法,批量复制方法copyWithin()以及填充数组方法fill()。他们不会改变原数组的大小。

fill()。 接收3个参数,第一个参数是要填充的内容,第二个是开始的索引,第三个是结束的索引。

const arr = [0, 0, 0, 0, 0];

arr.fill(5);//用5填充整个数组
console.log(arr); //[ 5, 5, 5, 5, 5 ]

arr.fill(0); //[0,0,0,0,0]
arr.fill(1, 3);  //用1填充索引大于等于3的元素
console.log(arr); //[ 0, 0, 0, 1, 1 ]

arr.fill(0); //[0,0,0,0,0]
arr.fill(1, 1, 3); //用1填充索引大于等于1且小于3的元素
console.log(arr); //[ 0, 1, 1, 0, 0 ]

fill()静默忽略超出数组边界、零长度及方向相反的索引范围:

const arr = [0, 0, 0, 0, 0];

//索引过低,忽略
arr.fill(1, -10, -6);
console.log(arr); //[ 0, 0, 0, 0, 0 ]

//索引过高,忽略
arr.fill(1, 10, 15)
console.log(arr); //[ 0, 0, 0, 0, 0 ]

//索引反向,忽略
arr.fill(2, 4, 2);
console.log(arr); //[ 0, 0, 0, 0, 0 ]

//索引部分可用,填充可用部分
arr.fill(4, 3, 10);
console.log(arr); //[ 0, 0, 0, 4, 4 ]

copyWithin()。 会按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置。开始索引和结束索引则与fill()使用同样的计算方法。

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]

//从arr中复制索引0开始的内容,插入到索引5开始的位置
arr.copyWithin(5);
console.log(arr); //[1, 2, 3, 4, 5,1, 2, 3, 4]

//从arr中复制索引5开始的内容,插入到索引0开始的位置
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.copyWithin(0, 5)
console.log(arr); //[6,7,8,9,5,6,7,8,9]

//从arr中复制索引0开始到索引3结束的内容,插入到索引4开始的位置
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.copyWithin(4, 0, 3)
console.log(arr); //[ 1, 2, 3, 4, 1, 2, 3, 8, 9]

3.增删数组元素

追加元素:

(1)用arr.length追加.

let arr = [1, 2, 3];
arr[arr.length] = 4;
console.log(arr); //[ 1, 2, 3, 4 ]

(2)用arr.push()追加.(返回新数组的长度)

let arr = [1, 2, 3];
let newArr = arr.push(4);
console.log(arr); //[ 1, 2, 3, 4 ]
console.log(newArr); //4

(3)用解构赋值追加。

let arr = [1, 2, 3];
arr = [...arr, 4]
console.log(arr); //[ 1, 2, 3, 4 ]

let arr = [1, 2, 3];
arr = [4, ...arr]
console.log(arr); //[ 4, 1, 2, 3 ]

(4)用arr.unshift()追加。(返回新数组的长度)

let arr = [1, 2, 3];
let newArr = arr.unshift(4);
console.log(arr); //[ 4, 1, 2, 3 ]
console.log(newArr); //4

(5)用arr.concat()合并数组

let arr1 = [1, 2, 3];
let arr2 = ['a', 'b', 'c']
let result = arr1.concat(arr2)
console.log(arr1); // [ 1, 2, 3 ]
console.log(arr2); // [ 'a', 'b', 'c' ]
console.log(result); //[ 1, 2, 3, 'a', 'b', 'c' ]

数组的截取移除:

(1)用arr.pop()移除数组最后面的一个元素。返回的是被移除的元素。

let arr = [1, 2, 3];
let value = arr.pop();
console.log(arr); //[ 1, 2]
console.log(value); // 3

(2)用arr.shift()移除数组最前面的一个元素。返回的是移除的元素。

let arr = [1, 2, 3];
let value = arr.shift();
console.log(arr); //[ 2, 3]
console.log(value); // 1

(3)用arr.slice()截取数组(不改变原数组) 左闭右开

let arr = [1, 2, 3, 4, 5, 6];
let newArr = arr.slice(1, 3);
console.log(arr); //[1, 2, 3, 4, 5, 6]
console.log(newArr); // [2, 3]

(4)用arr.splice() 截取数组(改变原数组) 有3个参数,第一个参数代表从哪开始截取,第二个参数代表截取的数量,第三个参数是要替换的内容。

let arr = [1, 2, 3, 4, 5, 6];
let newArr = arr.splice(1, 3);
console.log(arr); //[ 1, 5, 6 ]
console.log(newArr); // [ 2, 3, 4 ]
let arr = [1, 2, 3, 4, 5, 6];
let newArr = arr.splice(1, 3, 'aaa');
console.log(arr); // [ 1, 'aaa', 5, 6 ]
console.log(newArr); // [ 2, 3, 4 ]

很明显,这个splice()可以让我们在数组的指定的位置添加、删除、修改内容。

(5)使用arr.join()方法可以将数组转为字符串。该方法可以接收一个参数(字符串),该参数用于连接字符串,如果省略了参数,那么默认以','连接。

let arr1 = [1, 2, 3];
let arr2 = ['a', 'b', 'c']

console.log(arr1.join()); // 1,2,3
console.log(arr2.join('-')); // a-b-c

4.在数组中查找

数组中查找分为两类搜索数组的方法:按严格相等搜索和按断言函数搜索。

严格相等搜索方法:indexOf()、lastIndexOf()、includes()。都接收两个参数:要查找的元素和一个可选的起始搜索位置。这三个方法同字符串中使用这三个方法基本一致(详细请看第三章-string)。

(1)indexOf()

let arr1 = [1, 'abc', 2, 3, 'a', '324'];
console.log(arr1.indexOf('a')); //4
console.log(arr1.indexOf('b')); //-1

与字符串使用indexOf()的方法一样,从数组开头开始进行查找,如果找到就返回数组下标,如果没有找到就返回-1.

(2)lastIndexOf()

let arr1 = [1, 2, 3, 1, 2, 4];
console.log(arr1.indexOf(1)); // 0
console.log(arr1.lastIndexOf(1)); // 3
console.log(arr1.lastIndexOf('b')); // -1

该方法是从数组最后一个元素往前开始查找。

(3)includes()

let arr1 = [1, 2, 3, 1, 2, 4];
console.log(arr1.includes(1)); // true
console.log(arr1.includes('b')); // false

该方法返回的是boolean值。

(4)断言函数。

断言函数find()和findIndex()接收3个参数:元素、索引、数组本身。其中元素是数组中当前搜索的元素,索引是当前元素的索引,而数组就是正在搜索的数组。断言函数返回boolean值,表示是否匹配。

find()和findIndex()都从数组的最小索引开始。find()返回第一个匹配的元素,findIndex()返回第一个匹配元素的索引。这两个方法也都接收第二个可选参数,用于指定断言函数内部的this的值。

let arr = [1, 2, 3, 4, 5, 6];
let result = arr.find(function(item) {
    return item == 3
})
console.log(result); //3

result = arr.find(function(item) {
    return item == 10
})
console.log(result); //undefined

其实find()非常适合用于查找引用类型的数据。

let lessons = [
    { name: 'js' }, { name: 'css' }, { name: 'html' }
]
let result = lessons.find(item => item.name == 'css')
console.log(result); //{ name: 'css' }

findIndex()使用方法和find()一模一样,就是返回的值不一样。

let lessons = [
    { name: 'js' }, { name: 'css' }, { name: 'html' }
]
let result = lessons.findIndex(item => item.name == 'css')
console.log(result); // 1

5.数组的排序

数组有两个方法可以对数组进行重新排序:reverse()sort()reverse()就是将数组反向排序(均会改变原数组)。

let values = [1, 2, 3, 4, 5];
values.reverse();
console.log(values); //[ 5, 4, 3, 2, 1 ]

sort()默认情况下会按照升序重新排列数组元素,即最小的值在最前面,最大的值在后面。为此,sort()会在每一项上调用String()转型函数,然后比较字符串来决定顺序,即使数组的元素都是数值,也会把数组转换为字符串再比较、排序。

let values = [0, 1, 5, 10, 15];
values.sort();
console.log(values);  // [ 0, 1, 10, 15, 5 ]

一开始数组中的数值顺序是正确的,但是调用sort()会按照这些数值的字符串形式重新排序。因此,即使5小于10,但是字符串"10"在字符串"5"的前面,所以10还是会排到5前面。很明显,这在多数情况下都不是最合适的。为此,sort()方法可以接收一个比较函数,用于判断哪个值应该排在前面。

比较函数接收两个参数,如果第一个参数应该排在第二个参数前面,就返回负值(从小到大);如果两个参数相等,就返回0;如果第一个参数应该排在第二个参数后面,就返回正值。(从大到小)

我们可以这样记这个方法:传入的函数给定一对特定的元素a ,b 作为其两个参数,函数返回值大于0就是升序排列,如果是小于0就是降序!等于0就顺序不变。

let values = [0, 10, 5, 2, 15];
values.sort((a, b) => {
    return a - b < 0 ? -1 : 1 //升序
});
console.log(values); //  [ 0, 2, 5, 10, 15 ]

let values = [0, 10, 5, 2, 15];
values.sort((a, b) => {
    return a - b < 0 ? 1 : -1 //降序
});
console.log(values);   //[ 15, 10, 5, 2, 0 ]

等价于

let values = [0, 10, 5, 2, 15];
values.sort((a, b) => {
    return a - b //升序
});
console.log(values); //    [ 0, 2, 5, 10, 15 ]

let values = [0, 10, 5, 2, 15];
values.sort((a, b) => {
    return b - a //降序
});
console.log(values); //  [ 15, 10, 5, 2, 0 ]

明天更新总结数组的遍历、迭代方法(写不动了...)