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

对象操作

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); //遍历对象输出获得的是对象的key
		console.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 '#'"
    //当然也不用尝试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() {
    //下面所有例子分开console
    let 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) //返回 8
    console.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() {
	//length
	let 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')); //返回 1
	console.log('str',str.indexOf('e',2)); //第二个参数可以不传,表示从第几个开始查找,返回 11
},

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

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

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

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

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

testMethod() {
	let str = 'helloworldteststring';
	console.log('str',str.endsWith('string')); //返回 true
	console.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')); //返回 6
	console.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前边还有个空格
},

你可能感兴趣的:(JavaScript基础及实战,javascript,前端,vue.js)