- 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中判断数组长度不为零的正确姿势
// bad
if (arr.length !== 0) {
// todo
}
// good
if (arr.length) {
// todo
}
2、在if中判断数组长度为零的正确姿势
// bad
if (arr.length === 0) {
// todo
}
// good
if (!arr.length) {
// todo
}
3、简单的if判断使用三元表达式
// bad
if (a === 'a') {
b = a
} else {
b = c
}
// good
b = a === 'a' ? a : c
4、使用includes方法用来判断数组是否包含一个指定的值
// bad
if (a === 1 || a === 2 || a === 3 || a === 4) {
// todo
}
// good
let arr = [1, 2, 3, 4]
if (arr.includes(a)) {
// todo
}
- 巧用数组方法,尽量避免用for循环
5、使用some方法判断是否有满足条件的元素
// bad
let arr = [1, 3, 5, 7]
function isHasNum (n) {
for (let i = 0; i < arr.length; i ++) {
if (arr[i] === n) {
return true
}
}
return false
}
// good
let arr = [1, 3, 5, 7]
let isHasNum = n => arr.some(num => num === n)
// best
let arr = [1, 3, 5, 7]
let isHasNum = (n, arr) => arr.some(num => num === n)
6、使用forEach方法遍历数组,不形成新数组
// bad
for (let i = 0; i < arr.length; i ++) {
// todo
arr[i].key = balabala
}
// good
arr.forEach(item => {
// todo
item.key = balabala
})
7、使用filter方法过滤原数组,形成新数组
// bad
let arr = [1, 3, 5, 7],
newArr = []
for (let i = 0; i < arr.length; i ++) {
if (arr[i] > 4) {
newArr.push(arr[i])
}
}
// good
let arr = [1, 3, 5, 7]
let newArr = arr.filter(n => n > 4) // [5, 7]
8、使用map对数组中所有元素批量处理,形成新数组
// bad
let arr = [1, 3, 5, 7],
newArr = []
for (let i = 0; i < arr.length; i ++) {
newArr.push(arr[i] + 1)
}
// good
let 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快速获取对象键值*/
// bad
let keys = []
for (value in obj) {
keys.push(value)
}
// good
Object.keys(obj);
(3) ["a", "b", "c"]
/*使用Object.keys快速获取对象键名*/
// bad
let values = []
for (key in obj) {
values.push(obj[key])
}
// good
Object.values(obj);
(3) [1, 2, 3]
- 巧用解构简化代码
11、解构数组进行变量值的替换
// bad
let a = 1,
b = 2
let temp = a
a = b
b = temp
// good
let a = 1,
b = 2
[b, a] = [a, b]
12、解构对象
// bad
setForm (person) {
this.name = person.name
this.age = person.age
}
// good
setForm ({name, age}) {
this.name = name
this.age = age
}
// bad
const 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;
//good
const {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、解构时重命名简化命名
- 有的后端返回的键名特别长,你可以这样干
// bad
setForm (data) {
this.one = data.aaa_bbb_ccc_ddd
this.two = data.eee_fff_ggg
}
// good
setForm ({aaa_bbb_ccc_ddd, eee_fff_ggg}) {
this.one = aaa_bbb_ccc_ddd
this.two = eee_fff_ggg
}
// best
setForm ({aaa_bbb_ccc_ddd: one, eee_fff_ggg: two}) {
this.one = one
this.two = two
}
14、解构时设置默认值
// bad
setForm ({name, age}) {
if (!age) age = 16
this.name = name
this.age = age
}
// good
setForm ({name, age = 16}) {
this.name = name
this.age = age
}
15、|| 短路符设置默认值
let person = {
name: '张三',
age: 38
}
let name = person.name || '佚名'
16、字符串拼接使用 ${}
let person = {
name: 'LiMing',
age: 18
}
// bad
function sayHi (obj) {
console.log('大家好,我叫' + person.name = ',我今年' + person.age + '了')
}
// good
function sayHi (person) {
console.log(`大家好,我叫${person.name},我今年${person.age}了`)
}
// best
function sayHi ({name, age}) {
console.log(`大家好,我叫${name},我今年${age}了`)
}
17、处理多个条件
// bad
const conditions = ["Condition 2","Condition String2"];
someFunction(str){
if(str.includes("someValue1") || str.includes("someValue2")){
return true
}else{
return false
}
}
// good
someFunction(str){
const conditions = ["someValue1","someValue2"];
return conditions.some(condition=>str.includes(condition));
}
18、使用find()在数组中查找指定对象
- JavaScript find() 方法可用于搜索数组以查找特定对象。
- 如果是精确搜索用ES6中的find,性能优化,find方法中找到符合条件的项,就不会继续遍历数组。
- 模糊搜索一般用filter来实现
// bad
const 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];
}
}
//good
const 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、数组/对象合并数据(数组去重)
//bad
const 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}
//good
const 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 string
console.log(baz); // 0
21、拼接字符串(字符串模板多条件处理)
- 在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
//bad
const name = '小明';
const score = 59;
let result = '';
if(score > 60){
result = `${name}的考试成绩及格`;
}else{
result = `${name}的考试成绩不及格`;
}
//good
const 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 来实现
//bad
const 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);// 1
fn2().then(res2 =>{
console.log(res2)
})
})
}
// good
const fn = async () =>{
const res1 = await fn1();
const res2 = await fn2();
console.log(res1);// 1
console.log(res2);// 2
}
- 但是要做并发请求时,还是要用到Promise.all()。
const fn = () =>{
Promise.all([fn1(),fn2()]).then(res =>{
console.log(res);// [1,2]
})
}
- 如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
25、对象属性简写
//bad
const obj = { x:x, y:y };
//good
const obj = { x, y };
26、!! 将任何值转换为布尔值(除了false/0/“”)
!!true // true
!!2 // true
!![] // true
!!"Test" // true
!!false // false
!!0 // false
!!"" // false
- !!常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
- 判断变量a为非空,未定义或者非空串才能执行方法体的内容。
//bad
let a;
if( a != null && a != '' && typeof(a) != undefined ){
//执行代码
}
//good
if( !!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" }