对象操作

1. 扩展运算符 作用是遍历某个对象或者数组

testMethod() {// 三个点 ... 俗称扩展运算符或延展运算符,需要注意的是扩展运算符在拷贝的时候只能深拷贝第一层,第二层及以下都是浅拷贝,为了避免数据的影响,如果只是多层对象或数组的复杂关系,不推荐扩展运算符,除非你不在乎数据影响!let obj = {id: 1,name: 'xxx'};let obj2 = {...obj};console.log('obj',obj2) //输出obj {id: 1,name: 'xxx'}let arr = ['haha',{id: 1,name: 'xxx'},true];let arr2 = [...arr];console.log('arr',arr2) //输出arr ['haha',{id: 1,name: 'xxx'},true]
},

2. 枚举属性for in 用来遍历对象和数组

testMethod() {//但是不含 Symbol 属性哦let obj = {id: 1,name: 'xxx',age: 22};for (let stu in obj) {console.log('key',stu); //遍历对象输出获得的是对象的keyconsole.log('value',obj[stu]); //如果要获取对象key的值,可以通过 对象[stu或者具体的key名] 获取到值}let arr = ['haha',{id: 1,name: 'xxx',age: 22},false];for (let e in arr) {console.log('index',e); //遍历数组输出获得的是数组的下标console.log('value',arr[e]) //怎么通过下标获取数组的值我就不用多说了吧}
},

3. Object.assign() 用于将一个或多个可枚举但是仅限于对象本身(也就是说继承的不算)的属性的值复制到目标对象,然后返回目标对象

testMethod() {//如果拷贝的数据是基本类型,是深拷贝,如果是引用类型,是浅拷贝,语法:Object.assign(target, ...sources);let obj = {id: 1,name: 'xxx',age: 22};//复制一个对象给空对象let copyObj = Object.assign({},obj);console.log('copyObj',copyObj); //返回copyObj {id: 1,name: 'xxx',age: 22}//如果只有一个参数,会直接返回这个参数,如果参数不是对象,会转成对象然后返回,undefined和null无法转成对象,会报错,但是如果undefined和null不在源拷贝对象的第一个,就会被忽略,不会报错let copyObj2 = Object.assign(2);console.log('copyObj2',typeof copyObj2,copyObj2); //返回copyObj2 类型:object,值: Number {2}
},

4. Object.keys(obj) 返回对象所有可枚举并且是自身(继承不算)的属性名称组成的数组

testMethod() {let obj = {id: 1,name: 'xxx',age: 22, dept: {detpNo: 1,deptName: '学生会'}};console.log('objArr',Object.keys(obj)) //将对象的每个key名组成数组,输出['id', 'name', 'age', 'dept']//操作数组会返回数组的所有下标,字符串也一样,返回下标,不演示let arr = [1,2,3,4,5];console.log('arr',Object.keys(arr)) //将数组的下标作为字符串参数构成数组,返回['0', '1', '2', '3', '4']//常用技巧,获取到属性对应的值,做一些处理Object.keys(obj).map(key => {console.log('值',obj[key]); //这样就可以打印出值,咦,是不是发现和for in一样,其实是有区别的,后面说})
},

5. Object.values() 和上面keys相反的操作,返回对象所有可枚举并且是自身(继承不算)的 “属性值” 组成的数组

testMethod() {let obj = {id: 1,name: 'xxx',age: 22, dept: {detpNo: 1,deptName: '学生会'}};//是不是通过键名键值取到属性值很麻烦,js如此贴心,给你一个值组成的数组,你只要使用forEach()就可以取出来了console.log('arr',Object.values(obj)); //返回[1, 'xxx', 22, {detpNo: 1,deptName: '学生会'}]Object.values(obj).forEach(item => {console.log('值',item) //直接通过item获取到想要的值})
},

6. Object.entries() 上面两个的结合体,将键名和键值组成数组作为数组属性值返回,也就是返回一个二维数组

testMethod() {let obj = {id: 1,name: 'xxx',age: 22, dept: {detpNo: 1,deptName: '学生会'}};console.log('arr',Object.entries(obj)) //返回[["id",1],["name","xxx"],["age",22],["dept",{"detpNo": 1,"deptName": "学生会"}]]//二维数组怎么取值,在座各位心里自然清楚,就不再演示了
},

7. Object.freeze() 冻结对象,禁止对对象的一切操作,对象的原型链也不能操作

testMethod() {let obj = {id: 1,name: 'xxx',age: 22, dept: {detpNo: 1,deptName: '学生会'}};//首先将对象冻结Object.freeze(obj);//然后添加属性试试obj.className = '计算机网络1班';console.log('obj',obj); //打印出来发现,哎,添加不了,报错了 "TypeError: Cannot add property className, object is not extensible"//尝试修改,记得将上面的注释,js执行顺序从上到下,报错下面的不执行obj.id = 2;console.log('obj',obj); //打印出来发现,哎,修改不了,报错了 "TypeError: Cannot assign to read only property 'id' of object '#<Object>'"//当然也不用尝试delete删除对象的操作了,没啥卵用
},

8. hasOwnProperty() 用于检测一个对象自身是否含有特定的属性,返回布尔值

testMethod() {//h注意,不能获取到原型链上的属性,只能是自身let obj = {id: 1,name: 'xxx',age: 22, dept: {detpNo: 1,deptName: '学生会'}};//常用:判断一个对象本身是否有这个属性console.log('trueOrFalse',obj.hasOwnProperty('id')); //返回true//常用2: 遍历对象自身的属性的时候用来过滤原型链上的数据,下面举例子说明function objFn() {this.id = 2,this.name = 'haha',this.age = 22}//给原型上加属性objFn.prototype.className = '计算机网络1班';let obj2 = new objFn();for (let key in obj2) {console.log('键名',key) //通过返回发现,for in方法会同时返回原型链上的属性}//这样就很纳闷,有时候我们并不想获取原型链上的属性,只想获取当前对象本身的属性,这样就需要for in结合hasOwnProperty()方法实现for (let key in obj2) {if(obj2.hasOwnProperty(key)) {console.log('键名键值',key,obj2[key])}}//这样就了解了hasOwnProperty方法的使用,但是你会突然发现,这特么不就是Object.keys()方法吗,哈哈,所以for in和它的区别也就显而易见了
},

9. Object.getOwnPropertyNames() 用于返回一个由对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组

testMethod() {let obj = {id: 1,name: 'xxx',age: 22, dept: {detpNo: 1,deptName: '学生会'}};console.log('obj',Object.getOwnPropertyNames(obj)) //返回 ['id', 'name', 'age', 'dept']//话说我们怎么判断它可以包括不可枚举属性,来验证以下,通过defineProperty方法,我们可以给对象添加或者修改已经存在的属性,添加的属性将变成不可枚举Object.defineProperty(obj, "age", {value: 23});Object.defineProperty(obj, "className", {value: '计算机网络1班'});console.log('objDefine',obj) //返回这个对象{id: 1, name: 'xxx', age: 23, dept: {…}, className: '计算机网络1班'}//现在测试一下getOwnPropertyNames方法是否能返回不可枚举属性console.log('obj2',Object.getOwnPropertyNames(obj)) //我们发现返回了['id', 'name', 'age', 'dept', 'className']//Object.keys验证一下是否不返回不可枚举的属性console.log('obj3',Object.keys(obj)) //返回了['id', 'name', 'age', 'dept'],className这个不可枚举的字段没有返回,验证成功,所以这两者的区别又显而易见了
},

10. Object.getOwnPropertySymbols() 可以获取所有 Symbol类型的属性名放在数组中返回

testMethod() {let s1 = Symbol('a')let s2 = Symbol('b')let s3 = Symbol('c')console.log('symbol',s1,s2,s3) // 返回 Symbol(a) Symbol(b) Symbol(c)let obj = {k:'我的键名是字符串类型',[s1]:'haha',[s2]:'hehe',[s3]:'eeee'}console.log('obj',obj) // 返回 {k: '我的键名是字符串类型', Symbol(a): 'aaa', Symbol(b): 'bbb', Symbol(c): 'ccc'}console.log('arr', Object.getOwnPropertySymbols(obj))  //返回 [Symbol(a), Symbol(b), Symbol(c)],显而易见,k没有返回,它不是Symbol类型let objSymbols = Object.getOwnPropertySymbols(obj);console.log(obj[objSymbols[0]])//返回 haha,可以通过这种方式获取到值
},

11. in 判断对象中是否包含某个属性

//in直接返回boolean类型,in会判断继承过来的属性
let obj = {id: 1,name: 'xxx'};
let temp2 = 'name' in obj;
console.log('temp2',temp2) //返回true
let temp2 = 'toString' in {};
console.log('temp2',temp2) //会判断继承过来的属性,返回true

数组操作

1. push 在数组末尾添加一个或多个元素,并返回新数组长度

testMethod() {//下面所有例子分开consolelet arr = [];//添加一个数字或多个数字arr.push(1);arr.push(1,2,3);console.log('arr',arr) //返回 [1, 1, 2, 3]// 添加一个对象、多个对象或一个数组,多个数组arr.push({id: 1,name: 'aaa'})arr.push({id: 2,name: 'bbb'},{id: 3,name: 'ccc'})console.log('arr1',arr) //返回 [{id: 1,name: 'aaa'},{id: 2,name: 'bbb'},{id: 3,name: 'ccc'}]arr.push([1,2,3])arr.push([3,4,5],[6,7,8])console.log('arr2',arr) //返回 [[1,2,3],[3,4,5],[6,7,8]]//添加复合类型let num = arr.push('哈哈',true,100,undefined,null,["1",2],{id: 1,name: 'xxx'})console.log('arr3',arr) //返回 ['哈哈', true, 100, undefined, null, Array(2), {id: 1,name: 'xxx'}]console.log('num',num) //最后打印一下push后返回的数组长度,返回17,所以push返回值只会是数组长度
},

2. pop() 从数组末尾删除1个元素, 并返回被删除的元素

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2],{id: 1,name: 'xxx'}];let temp = arr.pop();console.log('删除的项',temp) //返回{id: 1,name: 'xxx'}console.log('原数组',arr) //返回['哈哈',true,100,undefined,null,["1",2]]
},

3. unshift() 在数组开始添加一个或多个元素,并返回新数组长度

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2],{id: 1,name: 'xxx'}];let temp = arr.unshift('哈哈1');console.log('新增的数组长度',temp) //返回 8console.log('原数组',arr) //返回 ['哈哈1','哈哈',true,100,undefined,null,["1",2]]
},

4. shift() 在数组开始删除一个元素,并返回被删除的元素

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2],{id: 1,name: 'xxx'}];let temp = arr.shift();console.log('删除的元素',temp) //返回 '哈哈'console.log('原数组',arr) //返回 [true,100,undefined,null,["1",2]]
},

5. toString() 将数组的每个元素转化为字符串,并且输入用逗号分隔的字符串列表

testMethod() {//同字符串操作方法,字符串模块不再讲解let arr = ['哈哈',true,100,undefined,null,["1",2],{id: 1,name: 'xxx'}];let temp = arr.toString();console.log('转换的元素',temp) //返回 哈哈,true,100,,,1,2,[object Object]//可以从上面的返回值看出,toString()方法会忽略undefined和null,但是位置还在,如果有多维数组,会降维处理,如果元素是对象,会返回[object Object]console.log('原数组',arr) //原数组不会改变,不信你打印看看
},

6. toLocaleString() 将数组的每个元素转化为字符串,并且输入用逗号分隔的字符串列表,字符串与执行环境的地区对应

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.toLocaleString();console.log('转换的元素',temp) //返回 哈哈,true,100,,,1,2,3,4,[object Object]console.log('原数组',arr) //原数组也不会改变//你是不是发现,这玩意不是和toString()返回值一样嘛,搞什么幺蛾子,细节来了,再来个例子let arr2 = [22223,2222,300,0.2];let arrNum = arr2.toLocaleString();console.log('arrNum',arrNum) //神奇时刻来了,返回值是 22,223 , 2,222 , 300 , 0.2//你说这怎么好几个逗号,老铁,这不就是分位符吗,那这还不能让你应景,再来个例子let date = new Date();let dateStr1 = date.toString();console.log('dateStr1',dateStr1) //这玩意返回 Fri Dec 02 2022 15:52:17 GMT+0800 (中国标准时间)let dateStr2 = date.toLocaleString();console.log('dateStr2',dateStr2) //这玩意返回 2022/12/2 15:52:17//兄弟们明白了吧,啥叫应景而生,有其他的新奇用法可以自己尝试
},

7. join() 将数组中所有元素都转化为字符串,通过指定分隔符进行分割并连接在一起,默认分隔符为逗号

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.join();console.log('temp',temp) //返回 哈哈,true,100,,,1,2,3,4,[object Object] //别着急,提到了指定分隔符,所以你想要什么都可以,花里胡哨,这就是和toString的唯一区别let temp1 = arr.join('|');console.log('temp1',temp1) //返回 哈哈|true|100|||1,2,3,4|[object Object]let temp2 = arr.join('&');console.log('temp2',temp2) //返回 哈哈&true&100&&&1,2,3,4&[object Object]let temp3 = arr.join('$');console.log('temp3',temp3) //返回 哈哈$true$100$$$1,2,3,4$[object Object]
},

8. indexOf() 从数组开头查找指定的元素,找到返回下标,没有找到返回 -1 方法有两个参数:查找的项和起点位置的索引(可填可不填)

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.indexOf(undefined)console.log('temp',temp) //返回下标 3 很明白,第四个let temp2 = arr.indexOf(undefined, 4) //还可以通过第二个参数指定从拿个下标开始找console.log('temp2',temp2) //返回 猜对没有返回什么,需要我说出来吗,不用想,肯定是-1,第五个开始就没有undefined嘛
},

9. lastIndexOf() 从数组末尾查找指定的元素,找到返回下标,没有找到返回 -1,只有一个参数

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.lastIndexOf(undefined)console.log('temp',temp) //返回下标 3 //这里提一嘴,你们可能会发现,不论是indexOf()还是lastIndexOf(),都不能找数组或者对象,原因是它们是根据引用地址查找,地址不同是找不到的,所以就不要做无谓的尝试了
},

10. reverse() 翻转数组,颠倒元素顺序

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.reverse();console.log('temp',temp) //别看我给了一个temp的变量,其实它会改变原数组,不信你打印一下arr//返回 [{id: 1,name: 'xxx'}, ["1",2,[3,4]], null, undefined, 100, true, '哈哈']
},

11. concat() 拼接数组 ,返回新数组,原数组不受影响

testMethod() {let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.concat(arr,[2,'haha2'],[3,'haha3']);console.log('temp',temp) //返回 ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'},2,'haha2',3,'haha3']//concat同样是字符串操作方法,拼接语法一致,下面不再讲解
},

12. slice() 截取数组生成新数组,牢记包头不包尾,原数组不受影响

testMethod() {//同时也是字符串操作方法,用法一致,下面字符串模块不再讲解let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];//这玩意真的挺复杂,不过做为保姆级教程,给你们贴心的分类好// 1.传一个参数,代表从第几个下标开始一直到最后console.log('arr',arr.slice(2)) //返回 [100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}]// 2.传一个参数,但是是负数,代表从倒数第几个一直到最后console.log('arr',arr.slice(-2)) //返回 [["1",2,[3,4]],{id: 1,name: 'xxx'}]// 3.传一个参数,但是超过数组的最大索引console.log('arr',arr.slice(10)) //返回空数组 [] // 4.传一个参数,是负数,但是也是大于索引的负数console.log('arr',arr.slice(-10)) //返回数组所有数据 ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}]// 5.传两个参数,第一个代表开始索引,第二个代表结束索引console.log('arr',arr.slice(3,5)) //返回 [undefined, null]// 6.传两个参数,第二个参数是负数,代表从第几个索引开始,截止到倒数第几个console.log('arr',arr.slice(4,-2)) //返回[null]// 7.传两个参数,结束索引超过数组最大索引、开始索引是负数并且超过数组最大索引、开始结束都是负数或正数并且都大于最大索引console.log('arr',arr.slice(3,10)) //这两个都会正常返回,返回从索引3开始到结束的元素console.log('arr',arr.slice(-10,10)) //返回所有数组console.log('arr',arr.slice(-10,-10));console.log('arr',arr.slice(10,10))//这俩都返回空数组
},

13. splice() 从数组中删除元素、插入元素到数组中或者同时完成这两种操作

testMethod() {//原数组会改变,所以进行下面打印每一行都是单独操作,自行注释let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];//本方法也是保姆级教程,共有三种方式// 1.传一个参数,代表删除当前索引之前的元素console.log('arr',arr.splice(4)) //返回 [null, ["1",2,[3,4]], {id: 1,name: 'xxx'}]// 2.传两个参数,代表从第几个元素开始,截取多少个console.log('arr',arr.splice(2,2)) //返回 [100, undefined],从索引2开始,也就是从第三个开始截取两个// 3.传三个以上参数,第一个代表从第几个元素开始,第二个代表删除多少个,第三个以后的参数代表将这些参数插入到刚删除的下标那里arr.splice(2,2,'aa','cc',false) //直接打印arr.splice(2,2,'aa','cc',false)是不会出现修改后的数组,只会出现删除的数组[100, undefined]console.log('arr',arr) //这儿打印返回修改后的数组 ['哈哈', true, 'aa', 'cc', false, null, ["1",2,[3,4]], {id: 1,name: 'xxx'}]
},

14. sort() 数组的排序方法

testMethod() {//这儿用一个数字数组和数组对象数组说明,分开打印let arr1 = [1, 10, 2, 20, 3];arr1.sort();console.log('arr1',arr1) //返回[1, 10, 2, 20, 3],很明显默认执行它不会排序arr1.sort((a,b) => { //升序方法return a - b;});console.log('arr1',arr1)  //返回[1, 2, 3, 10, 20]arr1.sort((a,b) => { //降序方法return b - a;});console.log('arr1',arr1)  //返回[20, 10, 3, 2, 1]let arr2 = [{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}];arr2.sort();console.log('arr2',arr2)  //默认不会排序,返回[{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}]arr2.sort((a,b) => { //升序方法return a.id - b.id; //指定根据id排序,也可以是其他参数});console.log('arr2',arr2) //返回 [{id: 1, name: 'bbb'},{id: 2, name: 'jjj'},{id: 3, name: 'aaa'},{id: 4, name: 'kkk'},{id: 5,name: 'ccc'}]arr2.sort((a,b) => { //降序方法return b.id - a.id;});console.log('arr2',arr2) //返回 [{id: 5,name: 'ccc'}, {id: 4, name: 'kkk'}, {id: 3, name: 'aaa'}, {id: 2, name: 'jjj'}, {id: 1, name: 'bbb'}]
},

15. forEach() 遍历数组,相当于for循环

testMethod() {//接收三个参数按顺序是:数组元素、元素的索引、数组本身let arr = [{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}];arr.forEach((item,index,arr) => {//item是每个元素,index是索引下标,arr是数组本身console.log('item',item, index, arr)//...可以在此做一些业务逻辑})
},

16. map() 遍历数组

testMethod() {//map方法和forEach都是用来循环数组,区别是map会返回一个新数组,不会改变原数组,和forEach接收的参数一样let arr = [{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}];let temp = arr.map((item,index,arr) => {console.log('接收参数',item,index,arr)return item.id < 3 ? item : ''; //猜猜这儿返回什么})console.log('temp',temp) //那么这儿打印一下上面的返回值 ['','',{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},'']console.log('arr',arr) //原数组不会改变,所以返回[{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}]//总结map()和forEach()的区别//1.map会返回新的数组,forEach不会返回数据//2.forEach允许callback更改原始数组的元素。map返回新的数组//综合来讲,forEach() 适合你并不打算改变数据而只是想用数据做一些事情的时候使用,map() 适合你要改变数据值的时候使用不仅仅在于它更快,而是返回一个新的数组;这样的优点在于你可以使用链式编程嵌套filter()、reduce() 等方法来组合玩出更多的花样
},

17. filter() 用于对数组进行过滤,返回一个新的数组

testMethod() {//不会检测空数组和改变原数组let arr = [{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}];let temp = arr.filter((item,index,arr) => {return item.id < 3;})console.log('temp',temp) //返回 [{id: 2,name: 'jjj'},{id: 1,name: 'bbb'}]//filter会直接根据条件返回一个由满足条件的参数构成的新数组,相当于条件查询,可以结合map方法生成新数据
},

18. every() 用于判断数组的所有元素是否都满足指定的条件,返回boolean类型,不会检测空数组和改变原数组

testMethod() {let arr = [{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}];let temp = arr.every((item,index,arr) => {return item.id > 0})console.log('temp',temp) //返回true//every方法为每个元素执行一个callback函数,如果return的是true就让它继续循环,有一个不满足条件的元素结果整个返回false,剩余的元素不会再执行检测,如果检测完数组的所有元素都满足条件返回true//所以说every函数体里面的return true并不会中止循环
},

19. some() 用于检测数组中的元素是否满足指定条件,和every反过来了,有一个元素满足条件,整个返回true,剩余的元素不会再执行检测

testMethod() {let arr = [{id: 3,name: 'aaa'},{id: 5,name: 'ccc'},{id: 2,name: 'jjj'},{id: 1,name: 'bbb'},{id: 4,name: 'kkk'}];let temp = arr.some((item,index,arr) => {return item.id === 2 //判断有没有id=2的元素存在})console.log('temp',temp) //返回true//some一样不会检测空数组和改变原数组,所有的元素都不满足就返回false
},

20. reduce() 归并类方法,最常用的场景就是,计算数组中的每一项的总和

testMethod() {//两个参数 function,初始值//function接收四个参数,前一个值,当前项,当前项索引,数组本身,只在第一个中演示let arr1 = [55,2,4,89,23];let temp1 = arr1.reduce((prev,cur,index,arr1) => {console.log('function参数',prev,cur,index,arr1)return prev + cur},10) //10是第二个参数:第一次累加的初始值console.log('temp1',temp1) //返回183 10 + 55 + 2 + 4 + 89 + 23//需要注意的是,当参数中出现字符串,后面的所有数字都会拼接而不是累加//还可以将二维数组转换成一位数组let arr2 = [[1,2,3],[4,5,6],[7,8,9]]let temp2 = arr2.reduce((perv,cur) => {return perv.concat(cur)},[])console.log('temp2',temp2) //返回[1, 2, 3, 4, 5, 6, 7, 8, 9]//还可以计算数组中每个元素出现的次数let arr3 = ['a','c','d','c','b','c','e']let temp3 = arr3.reduce((prev, cur) => {if (cur in prev) {prev[cur]++;} else {prev[cur] = 1;}return prev;}, {});console.log('temp3',temp3) //返回{a: 1, c: 3, d: 1, b: 1, e: 1}//还可以按属性对object分类let arr4 = [{id: 3,name: 'aaa',age: 20},{id: 5,name: 'ccc',age: 20},{id: 2,name: 'jjj',age: 21},{id: 1,name: 'bbb',age: 22},{id: 4,name: 'kkk',age: 20}];//调用方法let temp4 = groupBy(arr4,'age'); //按照age分组console.log('temp4',temp4) //返回太长,自己查看//按照属性分类的方法function groupBy(arr, objKey) {if (!Array.isArray(arr)) return [];return arr.reduce((prev, obj) => {var newObj = {[objKey]: obj[objKey],data: [obj],};if (!prev.length) {return [newObj];}for (let i = 0; i < prev.length; i++) {let item = prev[i];if (item[objKey] === obj[objKey]) {item.data = [...item.data, obj];return prev;}}return [...prev, newObj];}, []);}//还可以数组去重let arr5 = [{id: 3,name: 'aaa',age: 20},{id: 5,name: 'ccc',age: 20},{id: 2,name: 'jjj',age: 21},{id: 1,name: 'bbb',age: 22},{id: 4,name: 'kkk',age: 20}];let obj = {};let temp5 = arr5.reduce((prev,cur) => {//纯基本类型去重// return prev.includes(cur) ? prev : prev.concat(cur);//数组对象根据指定字段去重obj[cur.age] ? '' : obj[cur.age] = true && prev.push(cur);return prev;}, [])console.log('temp5',temp5)
},

21. reduceRight()

reduceRight()方法的功能和reduce()功能是一样的,不同的是reduceRight()从数组的末尾向前将数组中的数组项做累加。

22. includes() 用于查找特定属性是否存在,返回boolean类型

testMethod() {//可以查找元素是否在字符串中或者是否在数组中,需要传两个参数,第一个参数是查找的元素,第二个参数是开始索引,索引可以不传let arr = ['哈哈',true,100,undefined,null,["1",2,[3,4]],{id: 1,name: 'xxx'}];let temp = arr.includes(true,1); //查找true是不是在数组中console.log('temp',temp) //返回true//需要注意的是,如果要查找数组或者对象是否在数组中,就得转成字符串判断,毕竟严格来说这是字符串方法let temp1 = JSON.stringify(arr).includes(JSON.stringify({id: 1,name: 'xxx'}),1); //查找对象是否在数组中,返回true,自己测试//因为includes是字符串的方法,所以也可以直接查找字符是否在某个字符串中,和数组使用方法一致
},

字符串操作

1. length 获取字符串长度

testMethod() {//lengthlet str = 'helloworldteststring';console.log('strLength',str.length); //返回字符串长度   20
},

2. charAt() 获取字符串指定位置的字符

testMethod() {let str = 'helloworldteststring';console.log('str',str.charAt(4)); //返回对应字符   o
},

3. charCodeAt() 获取字符串指定位置字符的Unicode值

testMethod() {let str = 'helloworldteststring';console.log('str',str.charCodeAt(4)); //返回对应字符   111
},

4. indexOf() 检索字符串是否包含特定字符,有则返回第一次匹配到的下标位置,否则返回-1

testMethod() {let str = 'helloworldteststring';console.log('str',str.indexOf('e')); //返回 1console.log('str',str.indexOf('e',2)); //第二个参数可以不传,表示从第几个开始查找,返回 11
},

5. lastIndexOf() 检索字符串是否包含特定字符,有则返回最后一次匹配到的下标位置,否则返回-1

testMethod() {let str = 'helloworldteststring';console.log('str',str.lastIndexOf('e')); //返回 11console.log('str',str.lastIndexOf('e',9)); //第二个参数可以不传,表示从第几个开始从后往前查找,返回 1,但是具体的其实我也没怎么搞懂返回逻辑,自己摸索一下
},

6. startsWith() 检测字符串是否以指定的字符串开始。如果是以指定的字符串开头返回 true,否则 false。语法和上面的includes()方法一样

testMethod() {let str = 'helloworldteststring';console.log('str',str.startsWith('hello')); //返回 trueconsole.log('str',str.startsWith('world')); //返回 false
},

7. endsWith() 检测字符串是否以指定的字符串结尾。如果是以指定的字符串结尾返回 true,否则 false。

testMethod() {let str = 'helloworldteststring';console.log('str',str.endsWith('string')); //返回 trueconsole.log('str',str.endsWith('world')); //返回 false
},

8. split() 把一个字符串按照指定字符分割成字符串数组

testMethod() {//没有找到指定的字符就返回全部字符串,如果是空字符串就将每个元素用逗号分隔开,不会改变原始字符串let str = 'helloworld-teststring';console.log('str',str.split('-')); //返回 ['helloworld', 'teststring']//还可以传第二个参数limit限制返回的个数,超过限制不会返回console.log('str',str.split('-',1)); //返回 ['helloworld']
},

9. substr() 在字符串中截取从开始下标开始的指定数目的字符

testMethod() {//两个参数,start开始下标,length截取长度,不会改变原字符串let str = 'helloworldteststring';//传一个参数,返回从下标到结束的字符串console.log('str',str.substr(5)); //返回 worldteststring//传两个参数,返回从下标开始到第几个元素结束console.log('str',str.substr(5,5)); //返回 world//传一个负数参数,返回倒数下标开始到结束的字符串console.log('str',str.substr(-5)); //返回 tring//传两个参数,第一个负数,第二个正数,返回倒数下标开始到结束的字符串console.log('str',str.substr(-5,2)); //返回 tr//传两个负数参数console.log('str',str.substr(-5,-2)); //不报错,无返回值
},

10. substring() 用于提取字符串中介于两个指定下标之间的字符

testMethod() {//两个参数,from,to,因为是下标,所以都是非负正数,如果传负数,会忽略, 返回值包头不包尾let str = 'helloworldteststring';//传一个参数,返回从下标到结束的字符串console.log('str',str.substring(5)); //返回 worldteststring//传两个参数,返回从下标开始到下标结束的元素值,包头不包尾console.log('str',str.substring(5,6)); //返回 w
},

11. 字符串大小写转换

testMethod() {//字符串大小写转换let str = 'HelloWorldTestString';//1.toLowerCase() 把字符串转换为小写console.log('str',str.toLowerCase()); //返回 worldteststring//2.toUpperCase() 把字符串转换为大写console.log('str',str.toUpperCase()); //返回 w
},

12. replace() 字符串替换,不会改变原字符串,两个必填参数

testMethod() {//searchvalue:必需。规定子字符串或要替换的模式的 RegExp 对象。如果值是一个字符串,则将它作为要替换的文本,而不是首先被转换为 RegExp 对象。( RegExp 对象即正则表达式)//newvalue:必需。一个字符串值。替换的文本let str = 'Hello World Test String';console.log('str',str.replace('Hello','hi')); //返回 hi World Test String// 如果 regexp 具有全局标志 g,那么 replace() 方法将替换所有匹配的子串。否则,它只替换第一个匹配子串console.log('str',str.replace(/World/gi, "world")); //regexp返回 Hello world Test String
},

13. match() 用于在字符串内查找指定的值,或找到一个或多个正则表达式的匹配。

testMethod() {//类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置let str = 'Hello World Test String';console.log('str',str.match('World')); //返回 ['World', index: 6, input: 'Hello World Test String', groups: undefined]
},

14. search() 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,返回 str 中第一个与 regexp 相匹配的子串的起始位置

testMethod() {let str = 'Hello World Test String';console.log('str',str.search('World')); //返回 6console.log('str',str.search(/Test/)); //返回 12
},

15. 移除字符串空格

testMethod() {//移除字符串收尾空白符let str = ' Hello World Test String ';//1.trim()移除字符串首尾空白符,不能移除中间的字符,相当于下面两个结合体console.log('str',str.trim()); //返回 Hello World Test String//2.trimStart() 移除开始的空格console.log('str',str.trimStart()); //返回 Hello World Test String 后边还有个空格//3.trimEnd() 移除结尾的空格console.log('str',str.trimEnd()); //返回  Hello World Test String前边还有个空格
},

js对象、数组、字符串操作总结(保姆级教程)相关推荐

  1. FastText词向量训练、使用及可视化操作【保姆级教程(包含藏文处理方法)】

    目录 一.前言 二.FastText词向量训练 2.1 数据输入格式 2.2词向量训练 三.词向量使用 一.前言 本文是word2vec词向量篇的姊妹篇.fasttext是静态词向量构建方法的一种,本 ...

  2. Word2Vec词向量训练、使用及可视化操作【保姆级教程(包含藏文处理方法)】

    目录 一.前言 二.Word2Vec词向量训练 2.1 数据输入格式 2.2词向量训练 三.词向量使用 四.词向量可视化 一.前言 word2vec是静态词向量构建方法的一种,本文将介绍word2ve ...

  3. js 对象数组常用操作 我用到的

    1.删除一个元素 arr.splice(arr.findIndex(v => v.key === 'demokey'),1); 2.根据某个字段就行排序 function compare(p) ...

  4. 前端涨薪必读,node.js入门保姆级教程

    Node.js保姆级教程 1. Node基本概念 2. 第一个node.js程序 3. node创建get请求 4. node创建post请求 1. Node基本概念 1.1 node.js是什么? ...

  5. MySQL数据库篇---对数据库,数据库中表,数据库中表的记录进行添修删查操作---保姆级教程

    MySQL数据库知识点整理,保姆级教程 MySQL数据库存储方式 sql简介 SQL分类 DDL: 数据定义语言 DCL: 数据控制语言 DML:数据操控语言 DQL: 数据查询语言 SQL的使用 S ...

  6. js对象数组计算总计_如何计算数组中的对象

    js对象数组计算总计 Knowing how to quickly iterate through an array and count objects is deceptively simple. ...

  7. JS对象数组去重简单有效方法

    I.输入 JS对象数组去重是业务经常遇到的方法,稍微简洁一点的方法,如下: var data = [{"id": 1, "name": "李四1&qu ...

  8. js截取数组的操作 - Kaiqisan

    js截取数组的操作 hey みんなさんこんにちはKaiqisanと申します.一つの学生プログラマーである-,今天来讲一下截取数组的操作.由于我在项目的实践中总是会用到这个方法但是经常会忘记这些方法的时 ...

  9. js对象与字符串相互转换

    js对象与字符串相互转换 对象转为字符串 const obj = {id: 0,name: '张三',age: 12 } const objToStr = JSON.stringify(obj) co ...

最新文章

  1. 中国AI论文普遍水?机器学习教父Tom Mitchell的回答是……
  2. oracle创建数据库总结,oracle创建数据库和用户方法总结
  3. Twitter创始人Jack Dorsey的每日必做和不做清单
  4. wordpress发布模块_如何用WordPress打造出一个类似知乎的问答站点
  5. ue4 android vulkan,在Android用vulkan完成蓝绿幕扣像
  6. Starter Kit for ASP.NET 2.0 家族又添新丁!
  7. Android 之 Window、WindowManager 与窗口管理
  8. UI设计师,作品集该怎么做?场景展示样机更具专业性
  9. 我要做 Android 之 ContentProvider
  10. leetcode力扣62. 不同路径
  11. 群晖ds3617xs_23739虚拟机安装与半洗白教程
  12. 经典语录大全微信小程序源码下载多种分类语录多流量主模式
  13. 【网络编程】【SCTP】SCTP协议介绍,四次握手,三次挥手
  14. 用nvidia-docker跑深度学习模型
  15. jsp、html通过添加注册表打开本地应用
  16. C代码如何跑起来(程序编译和预处理)
  17. 485传感器接入串口交换机采集方案
  18. egg 调用html文件,egg怎么引入vue
  19. Static与Const的区别
  20. 命令配置bmc管理口

热门文章

  1. 做外贸用哪个收费邮箱好,好用的邮箱品牌推荐
  2. c++ascii码转换为数字_平面设计人员必备Image Ascii,快速将图像转换为Ascii字符画!...
  3. 半小时速通【页面数据分页】
  4. 写给未来的入职为程序员的人工智能专业的高考生的选专业看法
  5. 《Python之禅》——原文和翻译
  6. 国家开放大学2021春1054流通概论题目
  7. 乡村少年宫计算机小组活动教案,少年宫计算机组教案定稿版.docx
  8. SAP云产品部署方式及定价模型
  9. 计算机不能启动 无法验证数字签名,Win10提示错误0xc0000428无法验证此文件的数字签名怎么办?...
  10. 思科设备SSH登录配置