创建数组的方式
- 使用构造函数:
var arr = new Array();//()中可以传递数组数量,也可以传递item值(以逗号隔开)也可以忽略new操作符
当new Array(num)时(num代表单个数字),表示新建一个length=num的数组。当有多个num时,会会创建一个成员为nums的数组。可以省略new操作符。 - 使用数组字面量表示法
var arr = [];//[]中以,分开不同的item。不会调用Array构造函数。
JavaScript数组的特点
- 数组的大小动态调整(length属性不是只读)
通过修改length的值可以让数组从末尾移除项或者项数组中增加项 - 可以保存任意类型的数据
检测数组
if(value instanceOf Array){}
//instanceof的限制:只有一个执行环境。当你的项目中使用多个框架时,会存在两个不同版本的Array构造器
if(Array.isArray(value)){}
//更好的方法
内置方法总结
栈方法
栈是一种LIFO(Last-In-First-Out后进先出)。栈内元素的变化只发生在栈的顶部——数组的尾部。
push()和pop()两种方法模拟了栈的行为。
push()
接受任意数量的参数,将它们逐个添加到数组的末尾,并返回修改后数组的长度。
返回值:修改后数组的长度。
会修改原数组
pop()
从数组的末尾移除最后一项,减少length值,并返回移除的项。
返回值:移除的项
会修改原数组
队列方法
访问规则:FIFO(First-In-First-Out)。在列表的末端添加项,从列表的前端移除项。只存在一个方法的变化。
shift()和push()模拟了队列的行为
shift()
移除数组中的第一项并返回该项,同时将数组长度减一。
返回值:数组的第一项(被移除的项)
会改变原数组
unshift()
在数组前端添加任意个项并返回新数组的长度。
返回值:新数组的唱的
会改变原数组
重排序的方法
reverse()
反转数组项的顺序
返回值:新的数组
会改变原数组
sort()
调用每个数组项的toString()转型方法,将每个数组项以升序的方式排列数组项(最小值在最前面)。同时sort函数可以接受一个比较函数来自定义排序方法。比较函数接收两个参数,若第一个参数应该位于第二个参数前面,则返回一个负数。若两个函数相等则返回0.若第一个参数应该位于第二个参数后面,则返回一个正数。
例子:
function compare(value1,value2){
if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0
}
}
var values = [0,1,5,10,15];
values.sort(compare);
alert(values);
操作方法
concat()
基于当前数组中的所有项创建一个新数组
返回值:新数组
不会改变原数组
例子:
var colors = [1,2,3];
var colors2 = colors.concat(4,[5,6]);
console.log(colors)
console.log(colors2)
slice()
能够基于当前数组的一或者多个项创建一个新数组。
接受参数:一个或者两个
1. 一个参数
返回值:从该参数指定位置开始到当前数组末尾的所有项。
2. 两个参数
返回值:起始和结束位置之间的项——但不包括结束位置的项。
不会改变原数组
例子:
var colors = [1,2,3,4,5];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,3);
console.log(colors)
console.log(colors2)
console.log(colors3)
splice()
可以对数组进行删除、插入和替换操作
- 删除
接收两个参数:要删除的第一项的位置和要删除项的项数 - 插入
接收两个以上参数:起始位置,0(要删除的项数),要插入的项 - 替换
接收两个以上参数:起始位置,要删除的项数,要插入的项
返回值:删除的项组成的新数组(如果没有删除的项则返回一个空数组)
会改变原数组
例子:
var colors = [1,2,3,4,5];
var colors2 = colors.splice(0,1);
console.log(colors)
console.log(colors2)
colors2 = colors.splice(1,0,66,77);
console.log(colors)
console.log(colors2)
colors2 = colors.splice(1,1,88,99)
console.log(colors)
console.log(colors2)
位置方法
indexOf()
从数组开头开始向后查找
接收两个参数:要查找的项和(可选的)表示查找起点位置的索引
返回:要查找的项所在数组的第一个位置(index值),若没有找到,则返回-1
注意:比较方式为全等(===)
lastIndexOf()
从数组末尾开始向前查找。
接收参数:同上
返回:同上
迭代方法
均接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this值。传入的函数与接收三个参数:数组项的值、该项在数组中的位置和数组对象的本身。
every()
对数组的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
filter()
对数组中的每一项运行给定函数,返回该函数会返回true组成的数组
forEach()
对数组的每一项运行给定函数,该函数没有返回值
map()
对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
some()
对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。
entries()
返回一个遍历器对象,用来遍历键名,键值]组成的数组。对于数组,键名就是索引值;
let arr = ['a', 'b', 'c'];
for (let pair of arr.entries()) {
console.log(pair);
}
keys()
let arr = ['a', 'b', 'c'];
for (let pair of arr.keys()) {
console.log(pair);
}
values()
let arr = ['a', 'b', 'c'];
for (let pair of arr.values()) {
console.log(pair);
}
归并方法
reduce()
接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。传入的函数接收4个参数:前一个值,当前值,项的索引和数组对象。该传入函数返回的任何值都会作为第一个参数自动传给下一项。从前向后执行
reduceRight()
接收参数同上,但是从后向前执行。
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
return prev+cur;
})
console.log(sum);//15
ES6新增
扩展运算符的运用
/* 1. 复制数组
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组 */
const a1 = [1, 2]
const a2 = a1
a2[0] = 2
console.log(a1) //[2, 2]
//以上的情况发生原因是a2不是a1的克隆,而是指向同一份数据的林另一份指针。修改a2,会直接导致a1的变化,因为a2和a1共用一份内存空间
//通过扩展可以进行数组的复制
const a3 = [1, 2]
//写法一
const a4 = [...a3]
//写法二
const [...a5] = a3
a4[0] = 4
a5[0] = 5
console.log(a3, a4, a5)
/* 合并数组 */
const arr1 = ['a', 'b']
const arr2 = ['c']
const arr3 = ['d', 'e']
let arr4 = [...arr1, ...arr2, ...arr3]
let arr5 = arr1.concat(arr2, arr3)
arr1[0] = 'no'
console.log(arr4, arr1, arr5) // ["a", "b", "c", "d", "e"] ["no"] ["a", "b", "c", "d", "e"]
//都是浅拷贝
const array1 = [{ foo: 1 }]
const array2 = [{ var: 2 }]
const array3 = array1.concat(array2)
const array4 = [...array1, ...array2]
array1[0].foo = 2
console.log(array3, array4) //都是[{foo: 2},{var: 2}]
/* 与解构赋值结合 */
const [first1, ...rest1] = [1, 2, 3, 4, 5]
console.log(first1) // 1
console.log(rest1) // [2, 3, 4, 5]
const [first2, ...rest2] = []
console.log(first2) // undefined
console.log(rest2) // []
const [first3, ...rest3] = ['foo']
console.log(first3) // "foo"
console.log(rest3) // []
/* 字符串 */
let strArr = [...'hello']
console.log(strArr) //["h", "e", "l", "l", "o"]
/* 实现Iterator接口对象 */
Number.prototype[Symbol.iterator] = function*() {
let i = 0
let num = this.valueOf()
while (i < num) {
yield i++
}
}
console.log([...5])//[0,1,2,3,4]
//对Number对象定义遍历器接口,扩展运算符将5自动转成Number实例之后,就会调用这个接口,就会返回自定义的结果
函数参数的默认值
参数的变量是默认声明的,不能用let和const再次声明,否则会报错,同时使用参数默认值时,函数不能有同名参数。参数默认值不传值,每次都重新计算默认值表达式的值。
function Point(x=0,y=0){
this.x = x;
this.y = y;
}
const p = new Point();
console.log(p)
let x = 99;
function foo(p = x+1){
console.log(p)
}
foo()//100
foo()//100
x=100
foo()//101
Array.from()
将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象。
只要部署了Iterator接口的数据结构,Array.from都能将其转为数组。(如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组)
本质:任何有length属性的对象,都可以通过Array.from方法转成数组。
例子:
let arraylike = {
'0':'a',
'1':'b',
'2':'c',
length:3
}
let arr2 = Array.from(arraylike)
console.log(arr2)
Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,经处理后的值放入返回的数组。
let arraylike = {
'0':'1',
'1':'2',
'2':'3',
length:3
}
let arr = Array.from(arraylike,(x) => x*x)
console.log(arr)
Array.from的第一个参数可以指定第二个参数运行的次数
let arr = Array.from({length:2},() => 'jack')
console.log(arr)
Array.of()
用于将一组值,转换为数组。
与Array()可以比较
数组实例的copyWithin()
在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。(会修改当前数组)
接受三个参数:
- target(必需):从该位置开始替换数组。如果为负值,表示倒数。
- start(可选):从该位置开始读取数据,默认为0.如果为负值,表示从末尾开始计算
- end(可选):到该位置停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。不包括次位置的数
// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]
// 将3号位复制到0号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}
// 将2号位到数组结束,复制到0号位
let i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// 对于没有部署 TypedArray 的 copyWithin 方法的平台
// 需要采用下面的写法
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
[2,2,3,4,5].copyWithin(-1,3,4)
//[2,2,3,4,4]
数组实例的find()和findIndex()
数组实例的find方法,用于找出第一个符合条件的数组成员。
参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
findIndex与find函数非常相似,但是返回的是符合条件的第一个数组成员的位置,若都不符合返回-1
可以接受第二个参数,用来绑定回调函数的this对象
function f(v) {
return v > this.age
}
let person = { name: 'John', age: 20 }
let item = [10, 12, 26, 15].find(f, person)
console.log(item) //26
这两个数组都可以找到数组成员NaN
数组实例的fill()
fill方法接受第一个参数用于填充一个数组,同时也接受第二个——起始位置和第三个——结束位置(不包括该位置)用于指定填充。
如果填充的值是对象,这是一个浅拷贝
let arr = new Array(3).fill({ name: 'MIke' })
arr[0].name = 'Ben'
console.log(arr)
let arr2 = new Array(3).fill([])
arr2[0].push(5)
console.log(arr2)
数组实例的entries(),keys()和values()
keys()对键名进行遍历,values()对键值进行遍历,entires对键值对进行遍历
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b
数组实例的includes()
Array.prototype.includes()方法返回一个布尔值,表示某个数组是否包含给定的值。
接受第二个参数表示搜索的起始位置,默认为0,如果为负数,表示从末尾开始。如果大于数组长度,则会重置从0开始
数组实例的flat()、flatMap()
将嵌套的数组变成一维数组
返回的数据结构
- 字符串
- toString():返回每个值的字符串形式拼接而成的以逗号分隔的字符串。
- 数组中包括数组还是会按照出现的顺序log出来
- 数组中hr包含对象,log出来会是[object Object]的形式
2.join()
var arr1 = [1, [2.1, 2.2], 3];//logs 1,2.1,2.2,3 var arr2 = [1, {a: 1,b: 2}, 3];//logs 1,[object Object],3
- toString():返回每个值的字符串形式拼接而成的以逗号分隔的字符串。
- 数组
判断是否为数组类型: arr instanceOf Array- reverse(): 反转数组项的顺序,并返回数组。
- sort():调用toString()将item转成字符串进行升序排序,并返回数组。
- concat():创建当前数组的新副本,将接收到的参数添加到当前副本的末尾,最后返回新构建的数组。(原数组不发生变化)
- slice()[不影响原始数组,有第0位置]:
- 若参数只有1个,返回从该数组指定位置到当前数组末尾的所有项。
- 若参数有两个,返回起始和结束位置之间的项——但不包括结束位置的项。
- splice():返回从原数组中删除的项(若无,则返回一个空数组)[原数组发生改变]
- 删除——两个参数:要删除的第一项和删除的项数。
- 增加——三个参数以上:起始位置、0(要删除的项数)和要插入的项
- 替换——三个参数以上:起始位置、要删除的项数和要插入的任意数量的项。
- filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
- ma():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
- item
- pop():从数组末尾移除最后一项,减少了数组的length值,然后返回移除的项。
- shift():移除数组中的第一个项并返回该项,同时将数组长度减一。
- length
- push():将参数逐个添加到数组末尾,并返回修改后数组的长度,原来的数组受到改变。
- unshift():在数组的前端添加项,增加了数组的length值,然后返回数组的长度。
- index
- indexOf():从数组的开头开始向后查找,没找到返回-1,接收两个参数:要查找的项和查找起点位置(可选)
- lastIndexOf():从数组的末尾开始向前查找。没找到返回-1,,接收两个参数:要查找的项和查找起点位置(可选)
- 布尔值
- every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
- some():对数组中的每一项运行给定寒暑表,如果该函数对任一项返回true,则返回true
- 无返回值
- forEach():对数组中的每一项运行给定函数
对每一项都进行函数操作
every()
filter()
forEach()
map()
some()
reduce():返回的任何值都作为第一个参数自动传给下一项。
function(prev,cur, index, array)
reduceRight():方向不同。