- 1、在if中判断数组长度不为零的正确姿势
- 2、在if中判断数组长度为零的正确姿势
- 3、简单的if判断使用三元表达式
- 4、使用includes方法用来判断数组是否包含一个指定的值
- 5、使用some方法判断是否有满足条件的元素
- 6、使用forEach方法遍历数组,不形成新数组
- 7、使用filter方法过滤原数组,形成新数组
- 8、使用map对数组中所有元素批量处理,形成新数组
- 9、使用entries将Object属性转成属性数组
- 11、解构数组进行变量值的替换
- 12、解构对象
- 13、解构时重命名简化命名
- 14、解构时设置默认值
- 15、|| 短路符设置默认值
- 16、字符串拼接使用 ${}
- 17、处理多个条件
- 18、使用find()在数组中查找指定对象
- 19、数组/对象合并数据(数组去重)
- 20、空值合并运算符
- 21、拼接字符串(字符串模板多条件处理)
- 22、flat多维数组转一维数组(扁平化数组)
- 23、.?可选链运算符(访问深层嵌套的属性-将键名变成可选)
- 24、异步函数
- 25、对象属性简写
- 26、!! 将任何值转换为布尔值(除了false/0/“”)
- 27、reduce计算元素的总和
- 28、reduce计算和、最大值、最小值
JavaScript 标准内置对象 Object的所有方法
JavaScript 标准内置对象 Array的所有方法
1、在if中判断数组长度不为零的正确姿势
// badif (arr.length !== 0) {// todo}// goodif (arr.length) {// todo}
2、在if中判断数组长度为零的正确姿势
// badif (arr.length === 0) {// todo}// goodif (!arr.length) {// todo}
3、简单的if判断使用三元表达式
// badif (a === 'a') {b = a} else {b = c}// goodb = a === 'a' ? a : c
4、使用includes方法用来判断数组是否包含一个指定的值
// badif (a === 1 || a === 2 || a === 3 || a === 4) {// todo}// goodlet arr = [1, 2, 3, 4]if (arr.includes(a)) {// todo}
- 巧用数组方法,尽量避免用for循环
5、使用some方法判断是否有满足条件的元素
// badlet arr = [1, 3, 5, 7]function isHasNum (n) {for (let i = 0; i < arr.length; i ++) {if (arr[i] === n) {return true}}return false}// goodlet arr = [1, 3, 5, 7]let isHasNum = n => arr.some(num => num === n)// bestlet arr = [1, 3, 5, 7]let isHasNum = (n, arr) => arr.some(num => num === n)
6、使用forEach方法遍历数组,不形成新数组
// badfor (let i = 0; i < arr.length; i ++) {// todoarr[i].key = balabala}// goodarr.forEach(item => {// todoitem.key = balabala})
7、使用filter方法过滤原数组,形成新数组
// badlet arr = [1, 3, 5, 7],newArr = []for (let i = 0; i < arr.length; i ++) {if (arr[i] > 4) {newArr.push(arr[i])}}// goodlet arr = [1, 3, 5, 7]let newArr = arr.filter(n => n > 4) // [5, 7]
8、使用map对数组中所有元素批量处理,形成新数组
// badlet arr = [1, 3, 5, 7],newArr = []for (let i = 0; i < arr.length; i ++) {newArr.push(arr[i] + 1)}// goodlet arr = [1, 3, 5, 7]let newArr = arr.map(n => n + 1) // [2, 4, 6, 8]
let a = [{id:1}, {id:2}, {id:3},{id:4}]let ids = a.map(n => n.id).toString()console.log(ids);// 1,2,3,4,
9、使用entries将Object属性转成属性数组
- 巧用对象方法,避免使用for…in ```json 使用Object.entries(),Object.keys()和Object.values() const obj = { a: 1, b: 2, c: 3 };
Object.entries(obj); // 输出 (3) [Array(2), Array(2), Array(2)] 0: (2) [“a”, 1] 1: (2) [“b”, 2] 2: (2) [“c”, 3] length: 3
<a name="tjxfb"></a>### 10、Object.values/Object.keys快速获取对象键名和键值```json/*使用Object.values快速获取对象键值*/// badlet keys = []for (value in obj) {keys.push(value)}// goodObject.keys(obj);(3) ["a", "b", "c"]
/*使用Object.keys快速获取对象键名*/// badlet values = []for (key in obj) {values.push(obj[key])}// goodObject.values(obj);(3) [1, 2, 3]
- 巧用解构简化代码
11、解构数组进行变量值的替换
// badlet a = 1,b = 2let temp = aa = bb = temp// goodlet a = 1,b = 2[b, a] = [a, b]
12、解构对象
// badsetForm (person) {this.name = person.namethis.age = person.age}// goodsetForm ({name, age}) {this.name = namethis.age = age}
// badconst obj = {a:1,b:2,c:3,d:4,e:5,}const a = obj.a;const b = obj.b;const c = obj.c;const d = obj.d;const e = obj.e;const f = obj.a + obj.d;const g = obj.c + obj.e;//goodconst {a,b,c,d,e} = obj;const f = a + d;const g = c + e;
- 如果想创建的变量名和对象的属性名不一致,可以这么写:(a的值赋值给a1属性名)
const {a:a1} = obj;console.log(a1);// 1
- ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
const {a,b,c,d,e} = obj || {};
13、解构时重命名简化命名
- 有的后端返回的键名特别长,你可以这样干
// badsetForm (data) {this.one = data.aaa_bbb_ccc_dddthis.two = data.eee_fff_ggg}// goodsetForm ({aaa_bbb_ccc_ddd, eee_fff_ggg}) {this.one = aaa_bbb_ccc_dddthis.two = eee_fff_ggg}// bestsetForm ({aaa_bbb_ccc_ddd: one, eee_fff_ggg: two}) {this.one = onethis.two = two}
14、解构时设置默认值
// badsetForm ({name, age}) {if (!age) age = 16this.name = namethis.age = age}// goodsetForm ({name, age = 16}) {this.name = namethis.age = age}
15、|| 短路符设置默认值
let person = {name: '张三',age: 38}let name = person.name || '佚名'
16、字符串拼接使用 ${}
let person = {name: 'LiMing',age: 18}// badfunction sayHi (obj) {console.log('大家好,我叫' + person.name = ',我今年' + person.age + '了')}// goodfunction sayHi (person) {console.log(`大家好,我叫${person.name},我今年${person.age}了`)}// bestfunction sayHi ({name, age}) {console.log(`大家好,我叫${name},我今年${age}了`)}
17、处理多个条件
// badconst conditions = ["Condition 2","Condition String2"];someFunction(str){if(str.includes("someValue1") || str.includes("someValue2")){return true}else{return false}}// goodsomeFunction(str){const conditions = ["someValue1","someValue2"];return conditions.some(condition=>str.includes(condition));}
18、使用find()在数组中查找指定对象
- JavaScript find() 方法可用于搜索数组以查找特定对象。
- 如果是精确搜索用ES6中的find,性能优化,find方法中找到符合条件的项,就不会继续遍历数组。
- 模糊搜索一般用filter来实现
// badconst employess = [{name: "Paul", job_title: "Software Engineer"},{name: "Peter", job_title: "Web Developer"},{name: "Harald", job_title: "Screen Designer"},];for (let i = 0; i < employess.length; i++) {if(employess[i].job_title === "Software Engineer"){let sen = employess[i];}}//goodconst employess = [{name: "Paul", job_title: "Software Engineer"},{name: "Peter", job_title: "Web Developer"},{name: "Harald", job_title: "Screen Designer"},]let sen = employess.find(data => data.job_title === "Software Engineer")console.log(sen) // { name: 'Paul', job_title: 'Software Engineer' }
- findIndex查找对象在数组中的位置
19、数组/对象合并数据(数组去重)
//badconst a = [1,2,3];const b = [1,5,6];const c = a.concat(b);//[1,2,3,1,5,6]const obj1 = {a:1,}const obj2 = {b:1,}const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}//goodconst a = [1,2,3];const b = [1,5,6];const c = [...new Set([...a,...b])];//[1,2,3,5,6]const obj1 = {a:1,}const obj2 = {b:1,}const obj = {...obj1,...obj2};//{a:1,b:1}
20、空值合并运算符
- 空值合并运算符 (??) 是一个逻辑运算符
- 当其左侧操作数为空(null)或未定义(undefined)时返回其右侧操作数
const foo = null ?? 'default string';const baz = 0 ?? 42;console.log(foo); // default stringconsole.log(baz); // 0
21、拼接字符串(字符串模板多条件处理)
- 在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
//badconst name = '小明';const score = 59;let result = '';if(score > 60){result = `${name}的考试成绩及格`;}else{result = `${name}的考试成绩不及格`;}//goodconst name = '小明';const score = 59;const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
22、flat多维数组转一维数组(扁平化数组)
- 一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中
const deps = {'采购部':[1,2,3],'人事部':[5,8,12],'行政部':[5,14,79],'运输部':[3,64,105],}let member = [];for (let item in deps){const value = deps[item];if(Array.isArray(value)){member = [...member,...value]}}member = [...new Set(member)]
- 用Object.values来获取对象的全部属性值
- 数组的扁平化处理用ES6提供的flat方法来处理(多层嵌套for循环需要循环嵌套)
const deps = {'采购部':[1,2,3],'人事部':[5,8,12],'行政部':[5,14,79],'运输部':[3,64,105],}let member = Object.values(deps).flat(Infinity);
- flat方法不支持IE浏览器。
- flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。
[1, 2, [3, 4]].flat()// [1, 2, 3, 4]
[1, 2, [3, [4, 5]]].flat()// [1, 2, 3, [4, 5]][1, 2, [3, [4, 5]]].flat(2)// [1, 2, 3, 4, 5]
- 如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数
[1, [2, [3]]].flat(Infinity)// [1, 2, 3]
23、.?可选链运算符(访问深层嵌套的属性-将键名变成可选)
- 我们有时候为了访问深层嵌套的属性,一不小心就会报undefined的错,需要写一个很长的&&链去检查每个属性是否存在,代码如下
- 业务代码中经常会遇到这样的情况,a对象有个属性b,b也是一个对象有个属性c,
- 我们需要访问c,经常会写成a.b.c,但是如果f不存在时,就会出错
const a = {b: {c: 123,}}console.log(a.b.c); // 123;console.log(a.f.c); // f不存在所以会报错
- ECMAScript2020定义可选链运算符解决该问题,通过在.之前添加一个?将键名变成可选
let person = {};console.log(person?.profile?.age ?? 18); // 18
- 可选链运算符
let age = getUserInfo?.().data?.info?.age;
24、异步函数
- 异步函数很常见,经常是用 Promise 来实现
//badconst fn1 = () =>{return new Promise((resolve, reject) => {setTimeout(() => {resolve(1);}, 300);});}const fn2 = () =>{return new Promise((resolve, reject) => {setTimeout(() => {resolve(2);}, 600);});}const fn = () =>{fn1().then(res1 =>{console.log(res1);// 1fn2().then(res2 =>{console.log(res2)})})}// goodconst fn = async () =>{const res1 = await fn1();const res2 = await fn2();console.log(res1);// 1console.log(res2);// 2}
- 但是要做并发请求时,还是要用到Promise.all()。
const fn = () =>{Promise.all([fn1(),fn2()]).then(res =>{console.log(res);// [1,2]})}
- 如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
25、对象属性简写
//badconst obj = { x:x, y:y };//goodconst obj = { x, y };
26、!! 将任何值转换为布尔值(除了false/0/“”)
!!true // true!!2 // true!![] // true!!"Test" // true!!false // false!!0 // false!!"" // false
- !!常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
- 判断变量a为非空,未定义或者非空串才能执行方法体的内容。
//badlet a;if( a != null && a != '' && typeof(a) != undefined ){//执行代码}//goodif( !!a ){//执行代码}
27、reduce计算元素的总和
- 现在,我们将介绍它们之父,全能的 reduce 函数,您可以使用它编写自己的 map 、 filter 以及所有其他 Array 函数。
- reduce 方法包括将元素数组减少为单个值。它需要两个参数:
- 一个函数,它的第一个参数 previousValue 是到目前为止累积的值,
- 第二个参数 currentValue 是我们在这个数组中检查的当前值。它必须返回新的累加值。
- 一个初始值。在第一次迭代中,该值将用作previousValue
const elements = [1, 2, 3, 4, 5];const nextElements = elements.reduce((previousValue, currentValue) => previousValue + currentValue,0); // 15
- 这种方法只是将元素简化为其组成部分的总和。它本质上是添加它们,一次一个元素。
- 您是否注意到传递给 reduce 方法的函数有多简单?这是一个简单的总和!让我们将其重构为纯函数。
const elements = [1, 2, 3, 4, 5];const sum = (a, b) => a + b;const nextElements = elements.reduce(sum, 0); // 15
- 这段代码的美妙之处在于它的可读性。您可以从字面上阅读它的作用:它将元素减少到它们的总和。
- 现在,我们已经对使用虚拟示例的 reduce 方法有了很好的理解,我们可以使用它来计算所有用户余额的总和。
const users = [{name: "Jane",balance: 100,},{name: "John",balance: 75,},{name: "Ellis",balance: 31.3,},];const addBalance = (balance, user) => balance + user.balance;const balanceSum = users.reduce(addBalance, 0); // 206.3
- 它是编制统计数据和摘要的基础。这是您迟早必须要做的事情,使用 reduce 可以增强算法的风格和可读性。
28、reduce计算和、最大值、最小值
```json const array = [5,4,7,8,9,2];
/ 总和 / array.reduce((a,b) => a+b); // 输出: 35
/ 最大值 / array.reduce((a,b) => a>b?a:b); // 输出: 9
/ 最小值 / array.reduce((a,b) => a<b?a:b); // 输出: 2
<a name="YysiP"></a>### 29、 **Object.fromEntries() **[Array 转化为 Object](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries#array_%E8%BD%AC%E5%8C%96%E4%B8%BA_object)```json/* 必须是二维数组 */const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];const obj = Object.fromEntries(arr);console.log(obj); // { 0: "a", 1: "b", 2: "c" }
