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]
},
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]) //怎么通过下标获取数组的值我就不用多说了吧
}
},
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}
},
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一样,其实是有区别的,后面说
})
},
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获取到想要的值
})
},
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": "学生会"}]]
//二维数组怎么取值,在座各位心里自然清楚,就不再演示了
},
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删除对象的操作了,没啥卵用
},
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和它的区别也就显而易见了
},
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这个不可枚举的字段没有返回,验证成功,所以这两者的区别又显而易见了
},
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,可以通过这种方式获取到值
},
//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
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返回值只会是数组长度
},
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]]
},
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]]
},
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]]
},
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) //原数组不会改变,不信你打印看看
},
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
//兄弟们明白了吧,啥叫应景而生,有其他的新奇用法可以自己尝试
},
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]
},
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嘛
},
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(),都不能找数组或者对象,原因是它们是根据引用地址查找,地址不同是找不到的,所以就不要做无谓的尝试了
},
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, '哈哈']
},
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同样是字符串操作方法,拼接语法一致,下面不再讲解
},
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))
//这俩都返回空数组
},
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'}]
},
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'}]
},
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)
//...可以在此做一些业务逻辑
})
},
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() 等方法来组合玩出更多的花样
},
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方法生成新数据
},
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并不会中止循环
},
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
},
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)
},
reduceRight()方法的功能和reduce()功能是一样的,不同的是reduceRight()从数组的末尾向前将数组中的数组项做累加。
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是字符串的方法,所以也可以直接查找字符是否在某个字符串中,和数组使用方法一致
},
testMethod() {
//length
let str = 'helloworldteststring';
console.log('strLength',str.length); //返回字符串长度 20
},
testMethod() {
let str = 'helloworldteststring';
console.log('str',str.charAt(4)); //返回对应字符 o
},
testMethod() {
let str = 'helloworldteststring';
console.log('str',str.charCodeAt(4)); //返回对应字符 111
},
testMethod() {
let str = 'helloworldteststring';
console.log('str',str.indexOf('e')); //返回 1
console.log('str',str.indexOf('e',2)); //第二个参数可以不传,表示从第几个开始查找,返回 11
},
testMethod() {
let str = 'helloworldteststring';
console.log('str',str.lastIndexOf('e')); //返回 11
console.log('str',str.lastIndexOf('e',9)); //第二个参数可以不传,表示从第几个开始从后往前查找,返回 1,但是具体的其实我也没怎么搞懂返回逻辑,自己摸索一下
},
testMethod() {
let str = 'helloworldteststring';
console.log('str',str.startsWith('hello')); //返回 true
console.log('str',str.startsWith('world')); //返回 false
},
testMethod() {
let str = 'helloworldteststring';
console.log('str',str.endsWith('string')); //返回 true
console.log('str',str.endsWith('world')); //返回 false
},
testMethod() {
//没有找到指定的字符就返回全部字符串,如果是空字符串就将每个元素用逗号分隔开,不会改变原始字符串
let str = 'helloworld-teststring';
console.log('str',str.split('-')); //返回 ['helloworld', 'teststring']
//还可以传第二个参数limit限制返回的个数,超过限制不会返回
console.log('str',str.split('-',1)); //返回 ['helloworld']
},
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)); //不报错,无返回值
},
testMethod() {
//两个参数,from,to,因为是下标,所以都是非负正数,如果传负数,会忽略, 返回值包头不包尾
let str = 'helloworldteststring';
//传一个参数,返回从下标到结束的字符串
console.log('str',str.substring(5)); //返回 worldteststring
//传两个参数,返回从下标开始到下标结束的元素值,包头不包尾
console.log('str',str.substring(5,6)); //返回 w
},
testMethod() {
//字符串大小写转换
let str = 'HelloWorldTestString';
//1.toLowerCase() 把字符串转换为小写
console.log('str',str.toLowerCase()); //返回 worldteststring
//2.toUpperCase() 把字符串转换为大写
console.log('str',str.toUpperCase()); //返回 w
},
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
},
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]
},
testMethod() {
let str = 'Hello World Test String';
console.log('str',str.search('World')); //返回 6
console.log('str',str.search(/Test/)); //返回 12
},
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前边还有个空格
},