Array数组
1,创建数组:
// 1,字面量创建
let a = [1,2,3];
// 2,构造函数创建
let b = new Array(1,2,3);
// 注意:参数时数组长度
let c = new Array(3); // [empty × 4]
2,数组实例属性
// 实例属性length,表示数组长度
let a = ['a','b','c'];
0: "a"
1: "b"
2: "c"
length: 3 // 会自动维护length值
__proto__: Array(0) // 数组的原型对象
// 数组作为对象,索引也作为键
a["1"]; // "b"
a[1]; // "b"
3,数组原型方法
数组实例通过原型共享原型方法(可通过实例调用),下面是所有的原型方法:
- 搜索方法:
indexOf: ƒ indexOf()
lastIndexOf: ƒ lastIndexOf()
find: ƒ find()
findIndex: ƒ findIndex()
includes: ƒ includes()
> a // [ 'h', 'e', 'l', 'l', 'o', ',', 'J', 'S' ]
> a.indexOf(1); // -1 不存在则返回-1
> a.indexOf('e'); // 1
> a.lastIndexOf('J');// 6 逆序搜索
// includes()方法返回布尔值,表示是否存在
> a.includes('h'); // true
> a.includes(1); // false
// find() findIndex()条件查找第一个元素
> a.find( v=>v>'h'); // 'l' 返回元素值
> a.findIndex( v => v>'h'); // 2 返回索引
- 栈 队方法:
pop: ƒ pop()
push: ƒ push()
shift: ƒ shift()
unshift: ƒ unshift()
> a // [ 'h', 'e', 'l', 'l', 'o', ',', 'J', 'S' ]
// 删除则返回被删元素值,插入则返回length值
> a.pop(); // [ 'h', 'e', 'l', 'l', 'o', ',', 'J' ] 尾删
> a.push('Q'); // [ 'h', 'e', 'l', 'l', 'o', ',', 'J', 'Q' ] 尾插
> a.shift(); // [ 'e', 'l', 'l', 'o', ',', 'J', 'Q' ] 头删
> a.unshift('a'); // [ 'a', 'e', 'l', 'l', 'o', ',', 'J', 'Q' ] 头插
- 排序方法:改变原数组
sort: ƒ sort()
reverse: ƒ reverse()
> a // [ 'a', 'e', 'l', 'l', 'o', ',', 'J', 'Q' ]
> a.sort(); // 默认按ASCAII码从大到小排序
[ ',', 'J', 'Q', 'a', 'e', 'l', 'l', 'o' ]
> a.sort( (v1, v2) => v1-v2 ); // 返回负值v1排在前面,正值v2排在前面
[ 'o', 'l', 'l', 'e', 'a', 'Q', 'J', ',' ]
> a.reverse(); // 数组逆序
[ ',', 'J', 'Q', 'a', 'e', 'l', 'l', 'o' ]
- 复制填充方法:改变原数组
copyWithin: ƒ copyWithin()
fill: ƒ fill()
> a // [ ',', 'J', 'Q', 'a', 'e', 'l', 'l', 'o' ]
// copyWithin(target, start, end)
> a.copyWithin(0,1,4); // [1,4)元素依次拷贝到索引0处
[ 'J', 'Q', 'a', 'a', 'e', 'l', 'l', 'o' ]
// fill(value, start, end)
> a.fill('z',0,2); // [0,2)元素填充为'z'
[ 'z', 'z', 'a', 'a', 'e', 'l', 'l', 'o' ]
- 操作方法:
join: ƒ join()
concat: ƒ concat()
slice: ƒ slice()
splice: ƒ splice() 改变原数组!始终返回被删元素组成的数组
> a // [ 'z', 'z', 'a', 'a', 'e', 'l', 'l', 'o' ]
// join('连接符'):连接数组元素
> a.join(); // 默认','号分隔
'z,z,a,a,e,l,l,o'
> a.join('--'); // 返回拼接后的字符串
'z--z--a--a--e--l--l--o'
// concate(数组列表):合并数组
> a.concat(['J','S'],['E','S']); // 不会扁平化数组
[ 'z', 'z', 'a', 'a', 'e', 'l', 'l', 'o', 'J', 'S', 'E', 'S' ]
> a.concat(1,2,3);
[ 'z', 'z', 'a', 'a', 'e', 'l', 'l', 'o', 1, 2, 3 ]
// slice(start, end):获得子数组,start必须比end小
> a.slice(2,5); // [ 'a', 'a', 'e' ]
> a.slice(); // start默认起始,end默认结束位置
[ 'z', 'z', 'a', 'a', 'e', 'l', 'l', 'o' ]
> a.slice(5); // [ 'l', 'l', 'o' ]
> a.slice(-5,-1); // 负值会转换为 length+负值
[ 'a', 'e', 'l', 'l' ]
// splice(delstart, delcount, addItem); 改变原数组
> a.splice(1,3); // 删除[1,4)元素
[ 'z', 'a', 'a' ]
> a.splice(0,1,'h');// 替换[0]元素为'a'
[ 'h' ]
> a.splice(a.length,0,'J','S'); // 添加,返回[]
> a
[ 'h', 'e', 'l', 'l', 'o', 'J', 'S' ]
> a.splice(-2); // 负值同理
[ 'h', 'e', 'l', 'l', 'o' ]
- 归并方法:
reduce: ƒ reduce()
reduceRight: ƒ reduceRight()
> a // [ 'h', 'e', 'l', 'l', 'o' ]
// arr.reduce((prev,value,index,arr) => 逻辑代码,initvalue);
// 未指定initvalue则从[1]开始遍历,给定则从[0]开始遍历,
> a.reduce( (prev, value, index, arr) => prev+value);
'hello'
// 不同的只是遍历方向是 从右向左
arr.reduceRight((prev,value,index,arr)=> prev+value,initValue);
> a.reduceRight( (prev, value, index, arr) => prev+value,'#');
'#olleh'
- 迭代方法:
forEach: ƒ forEach()
every: ƒ every()
some: ƒ some()
filter: ƒ filter()
map: ƒ map()
> a // [ 'h', 'e', 'l', 'l', 'o' ]
// forEach((value,index,arr) => {逻辑代码}); 遍历
> a.forEach( (value,index,arr) => {if(value<'k') console.log(value);} );
h
e
// every((value,index,arr) => {逻辑代码}); 任意性
> a.every( (value,index,arr) => value>'a' ); // true
> a.every( (value,index,arr) => value>'f' ); // false
// some((value,index,arr) => {逻辑代码}); 存在性
> a.some( (value,index,arr) => value<'f' ); // true
> a.some( (value,index,arr) => value>'o' ); // false
// filter((value,index,arr)=>{逻辑代码}); 过滤
> a.filter( (value,index,arr) => value>'f' );
[ 'h', 'l', 'l', 'o' ]
// map((value,index,arr) => {逻辑代码}); 映射
> b = a.map( (value,item,arr) => value.charCodeAt() );
[ 104, 101, 108, 108, 111 ]
- 生成迭代器方法:
keys: ƒ keys()
values: ƒ values()
entries: ƒ entries()
a.keys(); // index 的迭代器
a.values(); // values 的迭代器
a.entries(); // [index, value] 的迭代器
- 转换方法:
toString: ƒ toString()
toLocaleString: ƒ toLocaleString()
values: ƒ values()
Object原型的方法:valueOf: ƒ valueOf()
```javascript
> a.toString(8); // 数组转换为字符串
'h,e,l,l,o'
> a.toLocaleString(); // 字符串本地化
'h,e,l,l,o'
> a.values();
Object [Array Iterator] {}
> a.valueOf(); // 返回数组对象的原始值
[ 'h', 'e', 'l', 'l', 'o' ]
在浏览器宿主环境中,新增了:
- 数组扁平化方法:
flat: ƒ flat()
flatMap: ƒ flatMap()
// flat()扁平化
> [1,[2,3,[4,5],6],7].flat(); // [1, 2, 3, Array(2), 6, 7] 默认扁平化1层
> [1,[2,3,[4,5],6],7].flat(2); // [1, 2, 3, 4, 5, 6, 7] 可以指定扁平化的层数
> [1,[2,3,[4,[5]],6],7].flat(Infinity); // [1, 2, 3, 4, 5, 6, 7] 无限扁平化
// flatMap(),相当于先映射再扁平化1层(只能扁平化1层)
> [1,2,3,4].flatMap(v => [v,v**2]);
[1, 1, 2, 4, 3, 9, 4, 16]
最后,简述一下数组的结构:
- 数组是一种JS内置的引用类型,通过构造函数定义的
- 函数也是对象,其中 prototype 属性指向其构造函数的原型
- 数组实例对象中,会有 __proto__ 属性指向其原型
- 数组的原型也是对象,实际上,是Object类型的实例对象
总之,JS中一切皆对象
即使是原始值,在调用属性和方法时,也会自动转为包装类对象。