前言
本人是一个刚入行的菜鸡前端程序员,写这个文章的目的只是为了记录自己学习的笔记与成果,如有不足请大家多多指点。
数组
数组是最简单的内存数据解构,数组存储一系列同一种数据类型的值。虽然在JavaScript里,也可以在数组中保存不同类型的值,但多数时候我们还是遵守最佳实践,要避免这么做。
创建和初始化数组
用 JavaScript 声明、创建和初始化数组很简单
let daysOfWeek = new Array() // (1)
daysOfWeek = new Array(7) //(2)
daysOfWeek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday') //(3)
使用new关键字,就能简单地声明并初始化一个数组(行(1))。用这种方式还可以创建一个指定长度的数组(行(2))。我们也可以直接将数组元素作为参数传递给它的构造器(行(3))。 用new创建数组并不是最好的方式。如果你想在JavaScript中创建一个数组,只用中括号([])的形式就行了,如下:
let daysOfWeek = []
也可以使用一些元素初始化数组 :
let daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
想知道数组中已经存了多少个元素,可以使用数组的length属性。
console.log(daysOfWeek.length) // 7
访问元素和迭代数组
要访问数组里特定位置的元素,可以用中括号传递数值位置,得到想知道的值或者赋新的值。假如我们想输出数组 daysOfWeek 里的所有元素,可以通过循环迭代数组、打印元素,如下:
for (let i = 0; i < daysOfWeek.length; i++) {
console.log(daysOfWeek[i])
}
例子:求斐波那契数列的前20个数。已知斐波那契数列中的前两项是 1,从第三项开始,每一项都等于前两项之和。
const fibonacci = [];
fibonacci[1] = 1;
fibonacci[2] = 1;
for (let i = 3; i < 20; i++) {
fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2]
}
for (let i = 1; i < fibonacci.length; i++) {
console.log(fibonacci[i])
}
如果想知道斐波那契数列其他位置上的值是多少,把循环条件中的终止变量从20改成你希望的值就行了
添加元素
在数组中添加和删除元素也很容易,但有时也会很棘手。假如我们有一个数组 numbers,初始化成了0到9
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
在数组的末尾插入元素
如果想要给数组添加一个元素(比如10),只要把值赋给数组中最后一个空位上的元素即可
numbers[number.length] = 10
使用push方法
还有一个push方法,能把元素添加到数组的末尾。通过push方法我们能添加任意个元素。
numbers.push(11);
numbers.push(12,13)
如果输出numbers的话,就会看到从0到13的值
在数组开头插入元素
我们希望在数组中插入一个新元素(数-1),不像之前那样插入到最后,而是放到数组的开头。为了实现这个需求,首先要腾出数组里第一个元素的位置,把所有的元素向右移动一位。我们可以循环数组中的元素,从最后以为(长度值就是驻足的末尾位置)开始,将对应的前一个元素(i-1)的值赋给它(i),依次处理,最后把我们想要的值赋给第一个位置(索引0上)。我们可以将这段逻辑写成一个函数,甚至将该方法直接添加在 Array 的原型上,使所有数组的实例都可以访问到该方法。
Array.prototype.insertFirstPosition = function(value) {
for (let i = this.length; i >= 0; i--) {
this[i] = this[i - 1];
}
this[0] = value
}
numbers.insertFirstPosition(-1)
使用 unshift 方法
在JavaScript里,数组有一个方法叫 unshift,可以直接把数值插入数组的开头(此方法背后的逻辑和insertFirstPostion方法的行为是一样的)
numbers.unshift(-2);
numbers.unshift(-4, -3);
删除元素
从数组末尾删除元素
要删除数组里最靠后的元素,可以使用 pop 方法
numbers.pop()
从数组开头删除元素
如果要移除数组里的第一个元素,可以用下面的代码
for (let i = 0; i < numbers.length; i++) {
numbers[i] = numbers.[i - 1]
}
但是,以上代码我们只是把数组第一位的值用第二位覆盖了,并没有实现真正意义上的删除(因为数组的长度还是和之前一样,并且多了一个未定义元素) 要真正从数组中移除这个元素,我们需要创建一个新的数组,将所有不是undefined的值从原来的数组复制到新的数组中,并且将这个新的数组赋值给我们的数组。创建一个 reIndex 方法
Array.prototype.redIndex = function(myArray) {
const newArray = []
for (let i = 0; i < myArray.length; i++) {
if(myArray[i] !== undefined) {
newArray.push(myArray[i])
}
}
return newArray
}
手动移除第一个元素并重新排序
Array.prototype.removeFirstPosition = function () {
for (let i = 0; i < this.length; i++) {
this[i] = this[i + 1]
}
return this.reIndex(this)
}
numbers = numbers.removeFirstPosition()
注:上面的代码只是示范作用,用于理解原理,在实际使用中我们应该始终使用 shift 方法
使用shift 方法
要删除数组的第一个元素,可以用shift 方法实现 numbers.shift()
在任意位置添加或删除元素
我们可以使用 splice 方法,简单地通过指定位置/索引,就可以删除相应位置上指定数量的元素。
numbers.splice(5,3)
删除从数组索引5开始的3个元素。 现在,我们想把 2、3、4 插入数组里,放到之前删除元素的位置上,可以再次使用splice方法。
numbers.splice(5, 0, 2, 3, 4)
splice 方法接收的第一个参数,表示想要删除或插入的元素的索引值。第二个参数是删除元素的个数。第三个参数往后,就是要添加到数组里的值。
二维和多维数组
JavaScript只支持一维数组,并不支持矩阵。但是我们可以通过数组套数组,实现矩阵或任意多维数组。
let averageTemp = []
averageTemp[0] = [23, 45, 35, 56, 33, 34]
averageTemp[1] = [32, 35, 23, 34, 23, 12]
迭代二维数组的元素
如果想看这个矩阵的输出,可以创建一个通用函数,专门输出其中的值。
function printMatrix(myMatrix) {
for (let i = 0; i < myMatrix.length; i++) {
for (let j = 0; j < myMatrix[i].length; j++) {
console.log(myMatrix[i][j])
}
}
}
多维数组
我们也可以用这种方式来处理多维数组。假设我们要创建一个 3 x 3 x 3 的矩阵,每一格里包含矩阵的i(行)、j(列)及z(深度)之和
const matrix3x3x3 = []
for (let i = 0; i < 3; i++) {
matrix3x3x3[i] = [] // 我们需要初始化每个数组
for (let j = 0; j < 3; j++) {
matrix3x3x3[i][j] = []
for (let z = 0; z < 3; z++) {
matrix3x3x3[i][j][z] = i + j + z
}
}
}
数组合并
有多个数组,需要合并起来成为一个数组。JavaScript给我嗯提供了解决方法,叫作 concat 方法。
const zero = 0;
const positiveNumbers = [1, 2, 3];
const negativeNumbers = [-3, -2, -1];
let numbers = negativeNumbers.concat(zero,positiveNumbers)
concat 方法可以向一个数组传递数组、对象或是元素。数组会按照该方法传入的参数顺序连接指定数组。zero将被合并到positiveNumvers中,然后positiveNumbers继续被合并。
迭代器函数
有时我们需要迭代数组中的元素,可以用循环语句来处理,例如for。 JavaScript 内置了许多数组迭代的方法。 假设数组中的值是从1到15;如果数组里的元素可以被2整除,函数就返回true,否则返回false。
function isEven(x) {
//如果 x 是 2 的倍数,就返回true
return x % 2 === 0 ? true : false
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
用every方法迭代
every 方法会迭代数组中的每个元素,直到返回 false。
numbers.every(isEven);
数组numbers的第一个元素是1,它不是2的倍数,因此 isEven 函数返回 false, 然后 every 执行结束。
用some方法迭代
some和every的行为相反,会迭代数组的每个元素,直到函数返回true
numbers.some(isEven);
numbers数组中的第一个偶数是2。isEven 返回 true —— 迭代结束
用forEach方法迭代
如果要迭代整个数组,可以用forEach方法。它和for循环的结果相同。
numbers.forEach( x => console.log( x % 2 === 0))
使用 map 和 filter 方法
这两个方法都会返回一个新的数组
const myMap = numbers.map(isEven)
myMap它保存了传入 map 方法的 isEven 函数的运行结果。 mymap 数组中的元素都是 true,false 组成。
const evenNumbers = number.filter(isEven)
filter 方法,它返回的新数组由函数返回 true 的元素组成。 evenNumbers 数组中的元素都是偶数。
使用reduce方法
reduce 方法接收一个有4个参数的函数: previousValue,currentValue,index和array。index和array是可选参数,用不到可以不用传。如果要对一个数组求和,这就很有用。
numbers.reduce( (previous,current) => previous + current )
ES6数组新功能
1.使用for...of 循环迭代
for (const n of numbers) {
console.log( n % 2 === 0 ? 'even' : 'odd')
}
2.使用@@iterator对象
ES6还为Array类增加一个@@iterator属性,需要通过 Symbol.iterator 来访问。
let iterator = numbers[Symbol.iterator]();
console.log(iterator.next().value) // 1
然后不断调用迭代器的 next 方法,就能依次得到数组中的值。数组中的所有制都迭代完成之后,iterator.next().value 会返回 undefined
3.使用from方法
Array.from 方法根据已有的数组创建一个新数组。比如,要复制numbers数组
let numbers2 = Array.from(numbers)
还可以传入一个用来过滤值的函数
let evens = Array.from(numbers, x => (x % 2 === 0))
4.使用Array.of方法
Array.of 方法根据传入的参数创建一个新数组。
let numbers3 = Array.of(1);
let numbers4 = Array.of(1, 2, 3, 4, 5, 6);
它和下面这段代码的效果一样
let numbers3 = [1]
let numbers4 = [1, 2, 3, 4, 5, 6]
5.使用fill方法
fill 方法用静态值填充数组
let numbersCopy = Array.of(1, 2, 3, 4, 5, 6)
numbersCopy数组的length是6
numbersCopy.fill(0)
numbersCopy数组所有位置上的值都会变成0。我们还可以指定开始填充的索引。
numbersCopy.fill(2, 1)
数组中从1开始的所有位置上的值都是2。 同样我们还可以指定结束填充的索引。
numbersCopy.fill(1, 3, 5)
把1填充到3到5的位置(不包括3和5)
6.使用copyWithin方法
copyWithin方法复制数组中的一系列元素到同一数组指定的起始位置。
let copyArray = [1, 2, 3, 4, 5, 6]
假如我们想把4、5两个值(在位置3、4上)复制到位置1和2,可以这样做:
copyArray.copyWithin(1, 3, 5)
会把位置3开始到位置5结束(包括3不包括5)的元素复制到位置1,结果得到数组 [1, 4, 5, 4, 5, 6]
排序元素
1.reverse
我们想反序输出数组 nummbers。要实现这样的功能,可以用reverse方法,然后数组内元素就会反序。
2.sort
sort 方法在对数组做排序时,把元素默认成字符串进行相互比较。 我们可以传入自己写的比较函数。
numvvers.sort((a, b) => a - b)
搜索
搜索有两个方法:indexOf方法返回与参数匹配的第一个元素的索引;lastIndexOf返回与参数匹配的最后一个元素的索引。
console.log(numbers.indexOf(10))
console.log(numbers.lastIndexOf(10))
ES6 - find 和 findIndex 方法
find 和 findeIndex 方法接收一个回调函数,搜索一个满足回调函数条件的值。
let numbers = [1,2,3,4,5,6,7,8,9,10]
function multipleOf7(element, index, array) {
return (element % 7 == 0)
}
console.log(numbers.find(multipleOf7))
console.log(numbers.findIndex(multipleOf7))
find 方法返回第一个满足条件的值, findIndex 方法则返回这个值在数组里的索引。如果没有满足条件的值, find 会返回 undefined ,而 findeIndex 返回 -1。
includes方法
如果数组里存在某个元素,includes 方法会返回true,否则返回false。
numbers.includes(14)
输出数组为字符串 toString 和 join
如果想把数组里所有的元素输出为一个字符串,可以用toString方法。
let arr = [1, 2, 3, 4, 5]
console.log(arr.toString()) // 1、2、3、4、5
如果想用一个不同的分隔符把元素隔开,可以用 join 方法。
let arr = [1, 2, 3, 4, 5]
console.log(arr.join('-')) // 1-2-3-4-5