js数组和对象的常见操作

一、创建一个数组

  • var ArrName = [new] Array(…elem)
  • var ArrName = Array.of(…elem)
  • var ArrName = […elem]
  • …elem代表可变参数,可以写入多个元素并且这些元素没有类型要求,
  • 当使用第一种方法的时候,当无参数时创建一个空数组,当参数为单个数字时创建一个具有个数为输入数字的空元素,个数大于等于2则为数字元素,new可不写
  • 使用 Array.of统一规则,无论几个参数都会创建由参数构成的数组
    当你的对超出范围的下标进行操作时,数组会通过添加空值达到你操作的下标
new Array(6) 结果:[empty × 6],而不会是含有6的数组
new Array(6,6) 结果: 这样就会创建一个[6, 6]的数组了
Array.of(6) 结果:[6]
[6,6] <=> new Array(6,6) <=> Array.of(6,6)
const arr = [6]
arr[6] = 1 结果: [6, empty × 5, 1] 
arr.length 结果: 7
  • 这里通常使用第二种,声明一个空数组再对其进行操作

二、数组元素操作

  • push(…item) 数组尾部插入一个或多个元素,返回插入后数组的长度
	var arr = [1,2]
	var arr2 = [3,4]
	arr.push(1,2)  结果: 4 - [1,2,1,2]
	arr.push(...arr2)  结果: 6 - [1, 2, 1, 2, 3, 4]
  • unshift(…item) 数组头部插入一个元素,返回插入后数组的长度
  • pop() 数组尾部删除一个元素,返回删除的数组元素
  • shift() 数组头部删除一个元素,返回删除的数组元素
  • length 取得数组的长度

三、数组方法

数组的合并 concat …

  • arr1.concat(arr2,arr3…) 可以传入多个参数,可以为空,返回合并后的数组,原数组不影响
  • arr1 = […arr2,…arr3,…] …arr1代表数组元素1,可以传入多个参数,返回合并后的数组
var arr = [1,2]
var arr2 = [3,4]
var arr3 = [5,6]
console.log(arr.concat(arr2,arr3))  结果:[1, 2, 3, 4, 5, 6]
console.log([...arr2,...arr3])  结果:[3, 4, 5, 6]

数组与字符串的转换 join、split

  • join( tag=‘,’ ) 默认将返回以逗号分隔的字符串,可以写入tag自定义分隔符
  • toString() 等同无参join()、String(arr)
  • […str] 返回分割每个字符的字符串
  • split( reg ) 按照reg正则或字符串分割字符返回数组,split(“”)分割每个字符,等价于[…str]、Array.from(arr)
arr = [1,3,9];
console.log(arr.join()) 结果:1,3,9
console.log(arr.join("-"))  结果:1-3-9
console.log(arr.toString()) 结果:1,3,9
console.log([..."hello"])  结果:["h", "e", "l", "l", "o"]
console.log("1,3,9".split(",")) 结果:["1", "3", "9"]
console.log("139".split(""))  结果:["1", "3", "9"]
console.log(Array.from("139"))  结果:["1", "3", "9"]

数组的截取 slice

返回截取的新数组,该数组有两个参数,start和end,分别代表截取起始结束为止,可不写,原数组不影响

arr = [2,4,1,9,3]
arr.slice()  结果:[[2,4,1,9,3]
arr.slice(1)  结果:[4,1,9,3]
arr.slice(1,3)  结果: [4, 1]
arr.slice(-1)[0] 结果: 3,等价于arr[arr.length-1]

注意:在js或者java中,当需要头尾参数时一般都是含头不含尾,并且头是从0开始计算

数组的增删改 splice

    这个方法非常强大,可以对数组进行指定index删除、增加、替换操作,返回结果为删除的数组元素,原数组受影响,他有三个参数,splice(index,number,…item)

  • index 代表删除的起始位置,可以为负数,代表反向起始位置,不写返回空数组对当前数组无影响,只有该值时代表从当前index位置一直到结束位置删除
  • number 代表删除的元素数目,删除替换当前元素可为1,为0则不会删除元素
  • …item 代表新增的数组元素,可以为多个
arr = [2,4,1,9,3] 
arr.splice(1)  结果:[4, 1, 9, 3] ,原数组[2] 
arr.splice(1,1)  结果: [4],原数组[2, 1, 9, 3] (删除单个元素)
arr.splice(1,0,5)  结果:[],原数组[2, 5, 1, 9, 3] (新增单个元素)
arr.splice(1,1,7)  结果:[5],原数组[2, 7, 1, 9, 3] (替换单个元素)

数组的排序 sort

    默认升序,可以通过匿名函数自定义排序规则,注意该函数在返回结果的同时会更改原数组

  • sort的数字默认比较会按照字符串比较,即"11"<“5”,需要自定义排序规则
  • 中文的排序使用匿名函数(a,b)=>a.localeCompare(b,"zh-CN")
arr = [2,4,11,9,3]
arr.sort()   结果: [11, 2, 3, 4, 9]
arr.sort((a,b)=> a-b)   结果:[234911]

数组的反转 reverse

    该函数在返回结果的同时也会更改原数组

arr = [2,4,1,9,3]
arr.reverse()  结果: [3, 9, 1, 4, 2]

数组的遍历 forEach、map、filter、reduce

    这里是ES5新增的方法,以下都不会更改原数组,并且每一个方法的回掉函数都至少有三个值,val、index、arr,分别代表当前遍历的元素值、索引以及遍历的数组对象

  • forEach 遍历所有元素
 var arr= [2,4,1];
   arr.forEach((item,index,arr) => {
     console.log(item,index,arr)
   })
结果:
   2 0  [2, 4, 1, 9, 3]
   4 1 [2, 4, 1, 9, 3]
   1 2  [2, 4, 1, 9, 3]

  • map 遍历所有的元素并返回处理后的数组
var arr= [2,4,1];
var result = arr.map((item,index,arr) => {
    return item*2
})
console.log(result)  结果: [4, 8, 2]
  • filter 遍历所有的元素并过滤符合条件的元素组成的数组
var arr= [2,4,1];
var result = arr.filter((item,index,arr) => {
    return item%2 === 0
})
console.log(result)  结果:[2, 4]
  • reduce 遍历所有的元素执行函数,生成一个值,可以有两个参数,第一个为回调函数,第二个为初始值(可不写,不写默认指向数组的第一个元素),回调函数的返回值都会作为下一次执行的第一个参数
  • reduceRight与reduce类似,不过是反向遍历
let arr= [2,4,1];
// arr.reduce((prev, curr) => prev+curr,0)
let result = arr.reduce((prev,curr,index) => {
  console.log(prev)   结果:0267
  return prev+=curr;
},0)
console.log(result)  结果:107

也可以将它们组合使用

var arr= [2,4,1];
var result = arr.filter(item => item%2 === 0).map(item => item*2)
console.log(result)  结果: [4, 8]

数组的校验 every、some、includes

  • every() 判断数组的每一项是否满足条件,所有都满足条件时才返回true,有一个为false即不继续执行
var arr= [2,4,5];
var arr2= [2,4,6];
arr.every(item => item%2 === 0)  结果:  false
arr2.every(item => item%2 === 0)  结果: true

  • some() 判断数组的每一项是否满足条件,有一个满足条件就返回true,有一个为true即不继续执行
var arr= [2,4,5];
var arr2= [1,3,7];
arr.some(item => item%2 === 0)  结果: true
arr2.some(item => item%2 === 0)  结果: false
  • includes(item,start) 查找元素等于item成功则返回true否则false
var arr= [2,4,5];
arr.includes(2)  结果: true
arr.includes(3)  结果: false
if(arr.includes(item)) 等价于 if(item === 2 || item === 4 || item === 5)

数组的查找 find、indexOf

  • find 返回符合条件的第一个元素(如果是对象,返回引用),查询不到返回undefined
  • findIndex 返回符合条件的第一个元素索引,查询不到返回-1
Arr = [2, 4, 1, 9, 3];
Arr.find((item,index,arr) => item>5);  结果: 9
Arr.find(item => item>9);  结果: undefined
Arr.findIndex(item => item>5);  结果: 3
Arr.findIndex(item => item>9);  结果: -1
  • indexOf(item,start) 正向查找成功返回查找元素的索引,不成功为-1,item为查找的元素,start为查找的起始位置可以不写,start可以为负数,反向计算起始位置
  • lastIndexOf(item,start) 从start开始(否则尾部)反向查找成功返回查找元素的索引,其余同上
arr =  [2, 1, 1, 9, 3]
arr.indexOf(9)  结果:  3
arr.indexOf(1,2)  结果: 2

数组的填充 fill

  • array.fill(value, start, end) 用于数组的填充,依次分别为value:填充的值,仅有此时填充所有,start:填充的开始位置,不指定结束位置则填充范围从该值到最后,end:填充的结束位置,返回且影响原数组
  • 如果填充的引用数据类型的话,则填充的元素都会指向同一个引用地址
 Array(20).fill(item)
 快速创建具有20个item的元素的数组

数组的展开 flat

  • flat(depth),depth是参数;指定要提取嵌套数组的结构深度,默认值为 1,返回新数组,如果你不知道有多少曾,可以把depth设置为Infinity
  • flatMap()方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组
  • 数组的原型对象上有一个方法,toString, 它能把数组的所以元素转化成用逗号隔开的字符串,join()、String(arr)同理,但这种方式不会区分字符串和数字类型,即使是数字也会转成字符串,flat则不会
let arr=[1,[2,[3,[4]]]]
arr.flat() 结果 [1, 2, Array(2)]
arr.flat(3)结果 [1, 2, 3, 4]
arr.flat(Infinity) 结果 [1, 2, 3, 4]
arr.toString().split(",") 结果:["1", "2", "3", "4"],join()、String(arr)亦可
[2, 3, 4].flatMap((x) => [x, x * 2]) 结果: [2, 4, 3, 6, 4, 8]

数组的移位 copyWithin

  • copyWithin(target, start, end),将索引start开始到end结束之前的元素复制带target位置上,可以不写end,那样默认复制start到target位置上,注意你操作的索引一定要在数组中存在才可以,否则可能会操作失败,该函数会影响并返回源数组
let arr = [1,2,3,4]
arr.copyWithin(0,2,4) 结果:  [3, 4, 3, 4]
arr.copyWithin(0,3) 结果: [4, 2, 3, 4]

四、数组的常见操作

数组的拷贝

但是如果数组嵌套了对象或者数组的话用concat、slice、…拷贝只要有修改会引起新旧数组都一起改变了(对象同理)
使用最后一种方法可以实现数组或对象的深拷贝,但不能拷贝函数,你也可以利用递归实现深拷贝

  • arr.slice()
  • arr.concat()
  • arr1 = […arr]
  • Array.from(arr)
  • JSON.parse(JSON.stringify(arr))
// 利于递归实现深拷贝
function deepCopy(source) {
     if (typeof source != "object") {
         return source;
     }
     if (source == null) {
         return source;
     }
     let newObj = Array.isArray(source)  ? [] : {};  //开辟一块新的内存空间
     for (let i in source) {
         newObj[i] = deepCopy(source[i]);
     }
     return newObj;
}

数组的合并

  • […arr1,…arr2,……]
  • arr1.concat(arr2,……)

数组的清空

  • arr.length = 0
  • arr.splice(0)
  • arr = []

数组的遍历(不用方法)

  • for i 遍历
  • for in 遍历,遍历元素为数组的索引
  • for of 遍历,遍历结果为数组的值(迭代器)
  • arr.keys(),arr.values(),arr.enties() 分别获取数字的索引、值、索引值的迭代器,使用for of迭代遍历,或者使用[…arr.keys()]将迭代器转为数组
var arr = [1,3,9];
for ( let i = 0; i <arr.length; i++)  console.log(arr[i]);  结果: 1,3,9
for(let item of arr) console.log(item)  结果:1,3,9
for(let item in arr) console.log(item)  结果:0,1,2
[...arr.keys()] 结果: [0, 1, 2]
for(let item of arr.keys()) console.log(item)  结果:0,1,2


五、对象的常见操作

对象的赋值

  • 对象中的值都会转成字符串(非字符串调用属性的toString方法),所以1和“1”是等价的,同理{a:1}和{b:1}也是一样的,因为他们的toString都是"[object Object]"
  • 可以动态给对象添加属性
  • 当对象中的参数为a:a,可以简写为a
  • 对象中方法名也可以简写
const obj = {}
const index = 666
obj[`name${index}`] = 'name666'
// 如果使用表达式直接声明赋值,需要写在方括号里
const obj2 = {[`name${index}`]:'name666'}
// 方法名简写
const person = {
  sayHi(){
    console.log("Hi");
  }
  上述等价于
  sayHi:function(){
    console.log("Hi");
  }
}

对象的遍历

  • for in遍历(包括原型链)
  • Object.keys() 获取所有键的数组
  • Object.values() 获取所有值的数组
  • Object.entries() 获取所有键值对的数组
let obj = {} //创建一个空对象,同样可以对对象进行置空操作
obj = {name:'jack',age:18}
for(let key in obj){
 console.log(key,obj[key])
}
结果: name jack
      age 18
         
Object.keys(obj) 结果:["name", "age"]
Object.values(obj) 结果:["jack", 18]
Object.entries(obj) 结果:[["name", "jack"],["age",18]]
Object.keys(obj).forEach(item=>{console.log(item,obj[item])})  
Object.entries(obj).forEach(([k,v])=>{console.log(k,v)})
结果:同for……in遍历

对象的合并 Object.assign…

  • Object.assign(target,…item) 合并多个对象至target对象中并返回合并后的target对象,如果不想对原对象产生改变,可以将target设置为{}即只有花括号的空对象
  • 使用…运算符也可以实现对象的合并,相当于Object.assign({},…item)
  • 以上两种方法拷贝时候同数组
let obj1= {name: 'liming', sex: '男'};
let obj2= {class: '一班', age: 15}; 
let obj3= {type: '学生', address: "安徽阜阳"};
Object.assign(obj1, obj2, obj3);
console.log(obj1);
结果:{name: "liming", sex: "男", class: "一班", age: 15, type: "学生", address: "安徽阜阳"}
let obj4 = {...obj1,...obj2,hobby:'dance'}
结果:{name: "liming", sex: "男", class: "一班", age: 15, hobby: "dance"}

对象元素的访问

    对象元素的访问可以通过对象名.元素名或者对象名[‘元素名’]的形式来访问,但使用中括号的时候元素名要加上引号,否则系统会把它当作一个变量名看待,你可以利用这一特性动态获取值
     || 符号当要输出的元素不存在即Boolean该元素为false的时候将会给予一个默认值,Boolean为false的情况有falseundefinednull0NaN‘’(空字符串)六种
     可以通过'属性名/方法名' in 对象名 来判断属性或方法是否存在于该对象,如果只判断方法可以使用对象方法的hasOwnProperty(‘属性名’)进行判断

let obj1= {name: 'liming', sex: '男'};
console.log(obj1.name)  结果:liming
console.log(obj1['name']) 结果:liming
console.log(obj1.address || "不详") 结果:不详
'name' in obj1 结果 true
'toString' in obj1 结果 true
obj1.hasOwnProperty('name') 结果 true

对象元素的删除 delete

delete 后直接跟空格对象元素,返回一个布尔值,删除对象无效

let obj1= {name: 'liming', sex: '男'};
delete obj1.name
结果:{sex: "男"}

对象元素的检测 hansOwnProperty、in

  • 通过hansOwnProperty可以检测自身时候具有某属性
  • 通过in不仅可以检测自身的还可以检测原型链上的
let obj1= {name: 'liming'};
obj1.hasOwnProperty('name') 结果:true
'name' in obj1 结果:true
obj1.hasOwnProperty('toString') 结果:false
'toString' in obj1 结果:true

判断对象是否为空

  • JSON.stringify(obj) == “{}”
  • Object.keys(obj).length === 0
  • Object.is(value1, value2) 用来比较两个值是否严格相等,与(===)基本类似

六、通用操作

对象转数组

  • 使用Array.from可以将类数组转为新的真正的数组,前提是这个类数组必须有length属性且有index索引属性名,就比如字符串,同时Array.from还有一个对函数进行处理的回调函数,每遍历到一个元素,便执行一次回调函数,就想map一样,不影响原类数组
  • 使用**Object.entries(obj)**可以将对象转为一个二维数组,每一维保存属性和值
let obj={0:1,1:2,length:3}
Array.from(obj) 结果: [1, 2, undefined]
Array.from({length:5},(i,index)=>index+1) 结果:[1, 2, 3, 4, 5]
Object.entries(obj)结果:[ ["0", 1],["1", 2],["length", 3]]

判断是对象还是数组arr

  • 判断是否为对象
    • Object.prototype.toString.call(obj) === '[object Object]
    • obj instanceof Object 可以判断是否为对象(数组也为true),也可以判断是否是具体的某个类的对象
  • 判断是否为数组
    • Object.prototype.toString.call(arr) == ‘[object Array]’
    • arr instanceof Array
    • Array.isArray(arr)

数组或对象的深拷贝

function deepCopy(obj){
    const o = Array.isArray(obj) ? [] : {}
    for(let key in obj){
        o[key] = (obj[key] instanceof Object) ? deepCopy(obj[key]):obj[key]
    }
    return o
}

七、相关知识点

…三点运算符

三点运算符是ES6的新特性,也是我用的最多的一个,它可以简便的进行数据的合并和拆解,其实就是当…位于左边作为变量或函数参数为合并,而放在右边赋值则为展开

  • 数组对象的解构

{ [objName]: realName=“default” } = obj;使用中括号[objName]读取动态属性的名称。realName变量接收动态属性的值。default代表objName不存在(undefined)时的默认值。如果objName和realName相等,可以只写一个,也就是对象字面量简写
对象属性可以不用定义,非对象必须定义

let obj={a:1,b:2,c:3};
let {a,...other}=obj 结果: a=1,other={b: 2, c: 3}
let arr = [1,2,3,4]
// 使用剩余参数接收剩下的数组或对象元素
let [a,...other]=arr 结果: a=1,ohter=[2, 3,4]
[obj.type]  = arr 结果:arr.type = 1
// 你还可以使用逗号跳过某个元素
let [,b,,c,d=1] = arr 结果: b=2,c=4,d=1
// 正如下面这样,你可以根据自己的需求进行解构,并不要求两边位置一一对应,也能使用默认值,
let [{a,b=5},[d,e,f=0],num,str=‘喔喔’]=[{a:3,b:4},[1,2,3],8]
var [obj,arr,num,str]=[{a:3,b:4},[1,2,3],8]
{target:{innerHTML:value='666'}} = e
console.log(value) 可以获取到event对象的HTML和设置默认值
// 字符串就是一个字符数组
let [a] = 'hello'; 结果: a='h'
  • 可变参数

当有多个参数时,可变参数必须放在最后一个

function show(...arr){
    console.log(arr)
}
show(1,2,3,4) 结果 [1, 2, 3, 4]
show(...[1,2,3,4]) 结果 [1, 2, 3, 4]
  • 展开运算符与合并对象数组
console.log(...arr) 结果 1 2 3
let arr1=[1,2]
let arr2=[3]
let arr3=[...arr1,...arr2] 结果 [1,2,3] 对象同理
  • 对象数组的浅复拷贝
let obj1 = {...obj}
obj1.a=99
结果:obj1 {a: 99, b: 2, c: 3}
	  obj  {a: 1, b: 2, c: 3}
let arr1 = [...arr]
arr1.length=2
结果  arr1 [1, 2]
	   arr [1, 2, 3]	
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信息技术王凤龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值