普通用字面量来创建数组,直接往[]中添加元素
let array = [ 1 , { name: 'xiaomin' , key: 12 } , 3 , 4 , 5 ] ;
console. table ( array) ;
用构造函数的方式创建数组,会有个问题,就是只往 Array()中放一个元素时,会被当作创建数组长度来解析
创建一个长度为 6 的数组,而不是创建一个长度为 1,元素为 6 的数组
let array = new Array ( 6 ) ;
console. table ( array. length) ;
新版的 js,给构造函数定义了一个新方法.of(),来创建一个或多个元素的数组
需要注意的是,用.of()方法,不能在 new 之后使用
let array = new Array. of ( 6 ) ; 报错!!
正确方式:
let array = Array. of ( 6 , 2 , 3 , 4 , 3 , { name: 'xu' } ) ;
console. table ( array) ;
判断一个变量是否是数组。用 Array.isArray()方法
console. log ( Array. isArray ( array) ) ;
数组转换成字符串的方法
第一种:数组.toString(),但是对于数组中元素含有对象类型的,就无法转换该元素
console. log ( array. toString ( ) ) ;
第二种:String(数组),但是对于数组中元素含有对象类型的,就无法转换该元素
console. log ( String ( array) ) ;
数组元素的拼接方法,数组.join(“符号”)
console. log ( array. join ( '-' ) ) ;
其他类型转换成数组类型
凡是有 length 属性的元素类型,都可以转换成数组
let str = "nihao,world" ;
console. log ( str. split ( "," ) ) ;
console. log ( Array. from ( str) ) ;
let obj = {
0 : "xu" ,
1 : 170 ,
2 : "xxx" ,
length: 3
}
console. log ( obj. length) ;
console. log ( Array. from ( obj) ) ;
console. log ( Array. from ( obj) ) ;
console. log ( Array. from ( obj, item=> {
return item* 2 ;
} ) )
展开语法总结:
展开语法放在变量的位置,就是吸星大法,将后面的内容都收到自己手里
let [ ... args] = [ 'a' , 'b' , 'c' ] ;
展开语法放在值的位置,就是冲破展开,将后面的内容全部冲散展开
let a = [ ... array] ;
let [ a, b, c] = [ ... array] ;
let [ a, b, c = 2021 ] = [ ... array] ;
console. log ( a, b, c) ;
数组的展开语法
console. log ( ... array) ;
字符串的展开语法
console. log ( ... str) ;
展开语法可以将其他类型转换成数组类型
let arr_str1 = [ ... str] ;
let [ ... arr_str1] = str;
console. log ( arr_str1) ;
展开语法可以将其他类型转换成对象类型
let obj_str1 = { ... str } ;
console. log ( obj_str1) ;
数组的展开语法妙用,将两个数组拼凑在一起
let arr1 = [ 'js' , 'css' , 'html' ] ;
for ( const item of arr1) {
array. push ( item) ;
}
console. log ( array) ;
array = [ ... array, ... arr1] ;
console. log ( array) ;
展开语法在函数中的妙用
在不知道传入的参数个数时,可以使用展开语法,将传入的参数形成一个数组,再对该数组进行操作
求和函数
function sum ( ... args) {
return args. reduce ( ( s, v) => {
return ( s += v) ;
} , 0 ) ;
}
console. log ( sum ( 1 , 3 , 4 , 5 ) ) ;
数组的结构赋值
即,定义一个对应的数组
let [ a1, a2] = array;
console. log ( a1, a2) ;
在函数的返回值中也一样,只要得到的值是一个数组,那么就可以用结构赋值的语法来获取到对应的值
function get ( ) {
return [ 1 , 3 , 45 , 7 , 8 , 3 ] ;
}
let [ a, b, c, d] = get ( ) ;
console. log ( a, b, c) ;
可以使用逗号进行占位,取非第一位元素
let [ , , a] = [ 1 , 2 , 3 , 4 ] ;
console. log ( a) ;
数组的填充 fill()
空数组用同一个元素填充
let array2 = new Array ( 4 ) ;
array2. fill ( 'a' ) ;
let array2 = new Array ( 4 ) . fill ( 'a' ) ;
数组元素的替换、填充
在已存在的数组元素上进行修改,不能增加超过数组长度的元素
fill(替代元素,起始下标,终止下标)
let array2 = [ 'a' , 'b' , 'c' ] ;
array2. fill ( 'xu' , 2 , 3 ) ;
console. log ( array2) ;
数组截取方法 1:slice(起始下标,终止下标) 不改变原数组!!!
返回的是截取片段(一样是数组类型),并不会改变原数组
如果 slice()中不写参数,则是将原数组简单复制一遍
let array2 = [ 1 , 2 , 3 , 4 , 'a' , 'c' ] ;
let sliceArr = array2. slice ( 4 , 6 ) ;
console. log ( sliceArr) ;
数组截取方法 2:splice(起始下标,截取长度) 改变原数组!!!
返回的是截取片段(一样是数组类型),是直接对原数组进行操作,所以原数组会被改变
如果 splice()中不写参数,则是截取一个空元素
如果 splice()中只写一个参数,则是以该参数为起始下标,截取后续所有元素
如果 splice()中写了 n>=3 个参数,则是正常执行移除操作后,再添加新元素,新元素内容:第 3 个参数到最后一个参数
let array2 = [ 1 , 2 , 3 , 4 , 'a' , 'b' ] ;
let spliceArr = array2. splice ( 0 , 1 , 1 , 2 , 3 , 4 ) ;
console. log ( spliceArr) ;
console. log ( array2) ;
清空数组的几种方式和区别
1、将数组置为空数组
缺点:不彻底,原数组是不发生改变的
因为数组是引用类型,所以只是传址,将数组置空,只是变量指向一个空数组,没有改变原数组的内容
let array2 = [ 1 , 2 , 3 ] ;
let cls = array2;
array2 = [ ] ;
console. log ( array2, cls) ;
2、将数组长度置为 0
优点:彻底将内存中的数组清空
let array2 = [ 1 , 2 , 3 ] ;
let cls = array2;
array2. length = 0 ;
console. log ( array2, cls) ;
3、用 splice()来清除数组
优点同 2,这是将数组的元素用截取的方法截走,而且不用其他元素来替代
let array2 = [ 1 , 2 , 3 ] ;
array2. splice ( 0 , array2. length) ;
console. log ( array2) ;
4、用弹栈的方式一个一个清除
缺点:需要知道数组长度才知道要 pop()多少次
let array2 = [ 1 , 2 , 3 , , , 5 , 55 , 4 ] ;
array2. pop ( ) ;
array2. pop ( ) ;
array2. pop ( ) ;
弹栈清除方式进阶,用 while 判断循环弹栈,判断弹出的元素是否为空(是否已弹完)
缺点:当数组中存在布尔值=false 的元素时,这个方法就终止了,就无法清空数组
while ( array2. pop ( ) ) {
console. log ( array2) ;
}
console. log ( array2) ;
拆分字符串成数组 split()
let arr = str. split ( ',' ) ;
console. table ( arr) ;
连接数组元素为字符串
let arr = str. split ( ',' ) . join ( '-' ) ;
console. log ( arr) ;
console. log ( typeof arr) ;
合并数组
1、concat()
let arr1 = [ 'nihao' , 'goodcode' ] ;
let arr = [ 1 , 2 , 3 ] ;
let arr2 = [ 'cd' , 'ab' ] ;
console. log ( arr2. concat ( arr, arr1) ) ;
2、concat()用展开运算符来代替
arr2 = [ ... arr2, ... arr, ... arr1] ;
console. log ( arr2) ;
数组内部元素的复制移动 copyWithin((复制到)目标位置,(截取的)起始位置,(截取的)终止位置)
将下标=2 到 下标=5 的所有元素,复制到下标=1 的位置
let arr = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ;
console. log ( arr. copyWithin ( 1 , 2 , 5 ) ) ;
数组的查找
需要注意,查找的元素是严格类型匹配,即:数组有字符串类型’9’,但是查找的方法中用的是数字类型 9,那么也是找不到的
1、indexOf() 返回元素在数组中的下标
查找方向:从前往后
let arr = [ 1 , 2 , 3 , 'nihao' , 5 , 6 , 7 , 1 , 'nihao' , { name: 'js' } ] ;
console. log ( arr. indexOf ( 'nihao' ) ) ;
console. log ( arr. indexOf ( 'world' ) ) ;
2、lastIndexOf() 返回元素在数组的下标
console. log ( arr. lastIndexOf ( 'nihao' ) ) ;
console. log ( arr. lastIndexOf ( 'world' ) ) ;
3、indexOf() 和 lastIndexOf() 的进一步使用:决定查找起始点
注:不能决定查找终止点
indexOf/lastIndexOf(要查找的元素,查找起始点)
console. log ( arr. indexOf ( 1 , 2 ) ) ;
console. log ( arr. indexOf ( 1 , - 1 ) ) ;
console. log ( arr. lastIndexOf ( 1 , 2 ) ) ;
console. log ( arr. lastIndexOf ( 1 , - 2 ) ) ;
4、includes() 返回 true 或 false,用于判断数组中是否有该元素,不在乎位置与数量
console. log ( arr. includes ( 'nihao' ) ) ;
console. log ( arr. includes ( 'world' ) ) ;
5、includes() 扩展,自己实现
普通写法:
function arr_includes ( array_in, find_value) {
for ( const item of array_in) {
if ( item === find_value) {
return true ;
}
}
return false ;
}
简化写法:
function arr_includes ( array_in, find_value) {
for ( const item of array_in) if ( item === find_value) return true ;
return false ;
}
console. log ( arr_includes ( arr, 'nihao' ) ) ;
6、includes()对于引用类型是返回 false 的
因为 includes()比对的是内存地址,传入的参数就像是新开辟的,当然和原数组中存储的元素的地址不一致
console. log ( arr. includes ( { name: 'js' } ) ) ;
7、find(function(item){}) 或 find(item=>{})
value 即为数组的每一项,index 即为对应的下标,find 遍历了整个数组
let result = arr. find ( ( value, index) => {
console. log ( value, index) ;
return value == 2 ;
} ) ;
console. log ( result) ;
8、利用 find()来查找数组中的引用类型元素
let result = arr. find ( ( item, index) => {
return item. name == 'js' ;
} ) ;
console. log ( result) ;
9、find()的兄弟函数 findIndex()
与 find()一致,findIndex()返回的是查找到的元素在数组中的下标
let result_index = arr. findIndex ( item => {
return item. name == 'js' ;
} ) ;
console. log ( result_index) ;
10、find()方法扩展,自己实现
function find ( arr_in, callback) {
for ( const item of arr_in) {
if ( callback ( item) ) {
return item;
}
}
return undefined;
}
console. log (
find ( arr, function ( value) {
return value == 'world' ;
} )
) ;
11、用数组原型来自己实现 find()
Array. prototype. findValue = function ( callback) {
for ( const item of this ) {
if ( callback ( item) ) {
return item;
}
}
return undefined;
} ;
console. log (
arr. findValue ( function ( value) {
return value == 'nihao' ;
} )
) ;
12、数组的排序-用于纯数字类型元素的比较
sort(a,b) a-b 为负数,从小到大;b-a 为整正数,从大到小
当数组中有非数字类型元素时,若第二元素个元素<第一个元素,会导致从大到小的情况失效
let arr_mix = [ 545 , 5261 , 32 , { name: 'ok' } , 5235 , 625 ] ;
arr_mix = arr_mix. sort ( function ( a, b) {
return b - a;
} ) ;
console. table ( arr_mix) ;
13、sort()扩展,自己实现
let arr_mix1 = [ 12 , 453 , 530000045 , 3242 , 3423 , 1000000 ] ;
function sortValue ( arr, callback) {
for ( const index_1 in arr) {
for ( const index_2 in arr) {
if ( callback ( arr[ index_1] , arr[ index_2] ) < 0 ) {
const temp = arr[ index_1] ;
arr[ index_1] = arr[ index_2] ;
arr[ index_2] = temp;
}
}
}
return arr;
}
arr_mix1 = sortValue ( arr_mix1, function ( a, b) {
return b - a;
} ) ;
console. log ( arr_mix1) ;
14、数组的循环
注意:当数组元素为引用类型时,可以通过操作让原数组发生改变;但数组类型为基本数据类型时,在 for 中的操作不会改变原数组
let lessons = [
{ title: '题1' , movie: '逃学威龙' } ,
{ title: '题2' , movie: '东邪西毒' } ,
{ title: '题3' , movie: '唐人的街' } ,
] ;
14.1、for() 通过下标来操作数组的每一项
for ( let i = 0 ; i < lessons. length; i++ ) {
lessons[ i] . title = `普通for修改后: ${ lessons[ i] . title} ` ;
}
console. table ( lessons) ;
14.2、for…of 直接获取到数组的每一项----------------------与第 15 点联系,这是使用迭代方法返回数组元素
for ( const item of lessons) {
item. title = `for_of修改后 ${ item. title} ` ;
}
console. table ( lessons) ;
for ( const value of lessons. values ( ) ) {
console. log ( value) ;
}
for ( const index of lessons. keys ( ) ) {
console. log ( index) ;
}
14.3、for…in 通过下标来操作数组的每一项
for ( let index in lessons) {
lessons[ index] . title = `for_in修改后 ${ lessons[ index] . title} ` ;
console. log ( value) ;
}
console. table ( lessons) ;
14.4、forEach(值,索引,原数组)
lessons. forEach ( ( key, index, lessons) => {
console. log ( key) ;
console. log ( index) ;
console. log ( lessons) ;
} ) ;
15、使用数组的迭代器 iterator
let lessons_it = [
{ title: '题1' , movie: '逃学威龙' } ,
{ title: '题2' , movie: '东邪西毒' } ,
{ title: '题3' , movie: '唐人的街' } ,
] ;
let values = lessons_it. values ( ) ;
console. log ( values. next ( ) ) ;
let indexs = lessons_it. keys ( ) ;
console. log ( lessons_it. keys ( ) ) ;
console. log ( indexs. next ( ) ) ;
console. log ( indexs. next ( ) ) ;
console. log ( indexs. next ( ) ) ;
console. log ( indexs. next ( ) ) ;
while ( ( { value, done } = values. next ( ) ) && done === false ) {
console. log ( value) ;
}
keys()、values()方法的综合 = entries()
let entries = lessons_it. entries ( ) ;
console. log ( entries. next ( ) ) ;
console. log ( entries. next ( ) . done) ;
console. log ( entries. next ( ) . value[ 0 ] ) ;
console. log ( entries. next ( ) . value[ 1 ] ) ;
let { value, done } = entries. next ( ) ;
console. log ( value, done) ;
let [ a, b] = value;
console. log ( 'index是:' + a, ' 元素内容是:' + JSON . stringify ( b) ) ;
let {
value: [ a, b] ,
done,
} = entries. next ( ) ;
console. log ( 'index是:' + a, ' 元素内容是:' + JSON . stringify ( b) ) ;
for ( const [ a, b] of entries) {
console. log ( 'index是:' + a, ' 元素内容是:' + JSON . stringify ( b) ) ;
}
16、every()方法,用于对数组中的所有数据进行统一判断,只要数组元素其中一个为假,则返回值=假
every 当中的函数返回值为布尔值!!!
判断学生成绩是否全部及格
let grades = [
{ name: '小明' , grade: 56 } ,
{ name: '小蓝' , grade: 75 } ,
{ name: '小红' , grade: 96 } ,
] ;
let res = grades. every ( function ( value) {
return value. grade >= 60 ;
} ) ;
console. log ( res ? '学生全部及格' : '有学生不及格' ) ;
17、some()方法,用于对数组中的所有数据进行统一判断,只要数组元素其中一个为真,则返回值=真
例子:input 的输入提示,是否包含某些关键字,不包含=假,包含其中一个=真
例子:判断数组中是否包含某些元素,不包含=假,包含其中一个=真
let res_1 = grades. some ( function ( value) {
return [ 'xiaomin' , '小红' ] . indexOf ( value. name) != - 1 ;
} ) ;
console. log ( res_1 ? '有小明或小红' : '没有小明或小红' ) ;
console. log ( res_1) ;
18、数组的过滤,filter(),用于筛选出有效的元素,返回的是布尔值=真的元素,可用一个新数组来接收
取一部分元素时,此函数较为适用,原数组如果是值类型,就没有发生变化;如果是引用类型,就会发生变化
let arr_new = arr. filter ( function ( value, index, arr) { return true ; }
例子:筛选出 grade>=60 的学生
let grade_ok = grades. filter ( function ( value) {
return value. grade >= 60 ;
} ) ;
console. table ( grade_ok) ;
18.1、filter()扩展,自己实现
function filterValue ( arr, callback) {
let arr_new = [ ] ;
for ( const item of arr) {
if ( callback ( item) ) {
arr_new. push ( item) ;
}
}
return arr_new;
}
console. log (
filterValue ( grades, function ( item) {
return item >= 60 ;
} )
) ;
19、map(),数组的映射操作-对数组进行操作,返回一个新数组或对原数组(引用类型)进行修改
map()返回什么,就是什么,可以用一个新数组来接收,原数组如果是值类型,就没有发生变化;如果是引用类型,就会发生变化
arr. map ( function ( value, index, arr) {
return '返回值' ;
} ) ;
19.1.1、引用类型数组-被改变
元素组已被改变!!!
grades. map ( function ( value) {
value. name = `修饰用-- ${ value. name} ` ;
return value. name;
} ) ;
console. log ( grades) ;
19.1.2、引用类型数组-不被改变
原数组未被改变!!!
用对象的 assign()合并方法,算是浅拷贝的一种
let changedArr = grades. map ( function ( value) {
return Object. assign ( { add: 100 } , value) ;
} ) ;
console. log ( changedArr) ;
console. log ( grades) ;
使用新创建键值的方式,将原数组的所有值都复制一份
let changedArr1 = grades. map ( function ( value) {
return {
name: `修使用-- ${ value. name} ` ,
grade: value. grade,
num: 11 ,
} ;
} ) ;
console. log ( changedArr1) ;
console. log ( grades) ;
19.2、数值型数组
let arr_num = [ 1 , 2 , 3 , 4 , 5 ] ;
let changedArr = arr_num. map ( function ( value) {
value += 1 ;
return value;
} ) ;
console. log ( changedArr) ;
console. log ( arr_num) ;
20、reduce(function(pre,value,index,arr){ },pre);
特殊点:这个函数比之前的函数多一个参数:pre,也就是"上一次这个函数的返回的结果"
如果没有返回结果,那么 pre=undefined
20.1、不给这个函数加 pre 的话,第一次遍历会将原数组的第一个参数当作 pre,第二个参数当作第 1 个 value
到第二次遍历的时候,由于函数没有返回值,就得不到 pre 的值了,pre=undefined
grades. reduce ( function ( pre, value, index, arr) {
console. log ( pre, value, index) ;
} ) ;
20.2、pre 的初始位置在 fucntion 之外,较为特殊
第一次 pre=原数组的第一个元素或者定义了的 pre 值
如果函数自带 return,返回的值=第二个 pre 的值
下例中,0 是初始的 pre 的值,所以第一次打印的 pre=0,由于这个函数没有 return,所以第二次及以后,pre=undefined
grades. reduce ( function ( pre, value, index, arr) {
console. log ( pre, value, index) ;
} , 0 ) ;
下例中,0 是初始的 pre 的值,所以第一次打印的 pre=0,由于这个函数有 return,所以第二次及以后,pre=‘第 n 次 pre’
grades. reduce ( function ( pre, value, index, arr) {
console. log ( pre, value, index) ;
return '第 n 次 pre' ;
} , 0 ) ;
20.3、例子:查询某值在数组中的重复次数
自己实现一个新方法
let arr_repeat = [ 1 , 2 , 3 , 4 , 3 , 2 , 3 , 2 , 1 , 5 ] ;
function query_num ( arr, num) {
return arr. reduce ( function ( pre, value) {
pre += value == num ? 1 : 0 ;
return pre;
} , 0 ) ;
}
console. log ( query_num ( arr_repeat, 2 ) ) ;
20.4、例子:获取数组中的最大值
自己实现一个新方法
let arr_repeat = [ 1 , 2 , 3 , 4 , 3 , 2 , 3 , 2 , 1 , 5 ] ;
function arr_MAX ( arr) {
return arr. reduce ( function ( pre, value) {
return pre > value ? pre : value;
} ) ;
}
console. log ( arr_MAX ( arr_repeat) ) ;
21、redcuce()的扩展应用
let shopCart = [
{ product: '毛巾' , price: 150 , discount: '七折' } ,
{ product: '面包' , price: 85 , discount: '五折' } ,
{ product: '水壶' , price: 260 , discount: '三折' } ,
{ product: '背包' , price: 16660 , discount: '四折' } ,
{ product: '鼠标' , price: 22260 , discount: '八折' } ,
] ;
21.1、查找价格最高的商品
function priceMax ( arr) {
return arr. reduce ( function ( pre, value) {
return pre. price > value. price ? pre : value;
} ) ;
}
console. log ( priceMax ( shopCart) ) ;
21.2、将所有商品的价格进行汇总
function totalPrice ( arr) {
return arr. reduce ( function ( pre, value) {
return ( pre += value. price) ;
} , 0 ) ;
}
console. log ( totalPrice ( shopCart) ) ;
21.3、查找商品价格超过 1w 元的商品名字
第一种写法:
function over1w ( arr, price1w) {
return arr
. reduce ( function ( pre, value) {
if ( value. price > price1w) {
pre. push ( value) ;
}
return pre;
} , [ ] )
. map ( function ( item) {
return item. product;
} ) ;
}
console. log ( over1w ( shopCart, 10000 ) ) ;
第二种写法:
function more1w ( arr) {
let b = [ ] ;
for ( const item_name of arr. filter ( function ( value) {
return value. price >= 10000 ;
} ) ) {
b. push ( item_name. product) ;
}
console. table ( b) ;
}
more1w ( shopCart) ;
第三种写法:
function more1w ( arr) {
return arr
. filter ( function ( value) {
return value. price >= 10000 ;
} )
. map ( function ( value) {
return value. product;
} ) ;
}
console. log ( more1w ( shopCart) ) ;
21.4、数组去重
思路:用一个空数组来存不重复的元素,用 includes()方法判断当前该元素是否存在于新数组中,如果存在,就不加入到新数组当中
pre = [],可以用来迭代一个没有重复元素的数组
21.4.1、纯数字类型数组去重
let arr_repeat = [ 1 , 3 , 2 , 3 , 4 , 56 , 2 , 3 , 4 , 5 , 5 , 5 , 5 ] ;
let a = arr_repeat. reduce ( function ( pre, value) {
if ( ! pre. includes ( value) ) {
pre. push ( value) ;
}
return pre;
} , [ ] ) ;
console. log ( a) ;
21.4.2、引用类型数组去重
思路:由于存储的是对象,所以用 includes()方法明显是不能操作对象的属性
所以要用 find()方法,当找到已存在的相同属性值的时候,find()返回的是该元素(布尔值=true),这时不将此元素加入到新的空白数组中就可以了
let arr_repeat_obj = [
{ product: '毛巾' , price: 150 , discount: '七折' } ,
{ product: '面包' , price: 85 , discount: '五折' } ,
{ product: '鼠标' , price: 225346 , discount: '一折' } ,
{ product: '水壶' , price: 260 , discount: '三折' } ,
{ product: '背包' , price: 16660 , discount: '四折' } ,
{ product: '鼠标' , price: 22260 , discount: '八折' } ,
{ product: '鼠标' , price: 2434 , discount: '九折' } ,
] ;
let a = arr_repeat_obj. reduce ( function ( pre, value) {
if (
! pre. find ( function ( pre_item) {
return pre_item. product == value. product;
} )
) {
pre. push ( value) ;
}
return pre;
} , [ ] ) ;
console. log ( a) ;