JavaScript 标准内置对象 Object的所有方法
JavaScript 标准内置对象 Array的所有方法

1、在if中判断数组长度不为零的正确姿势

  1. // bad
  2. if (arr.length !== 0) {
  3. // todo
  4. }
  5. // good
  6. if (arr.length) {
  7. // todo
  8. }

2、在if中判断数组长度为零的正确姿势

  1. // bad
  2. if (arr.length === 0) {
  3. // todo
  4. }
  5. // good
  6. if (!arr.length) {
  7. // todo
  8. }

3、简单的if判断使用三元表达式

  1. // bad
  2. if (a === 'a') {
  3. b = a
  4. } else {
  5. b = c
  6. }
  7. // good
  8. b = a === 'a' ? a : c

4、使用includes方法用来判断数组是否包含一个指定的值

  1. // bad
  2. if (a === 1 || a === 2 || a === 3 || a === 4) {
  3. // todo
  4. }
  5. // good
  6. let arr = [1, 2, 3, 4]
  7. if (arr.includes(a)) {
  8. // todo
  9. }
  • 巧用数组方法,尽量避免用for循环

5、使用some方法判断是否有满足条件的元素

  1. // bad
  2. let arr = [1, 3, 5, 7]
  3. function isHasNum (n) {
  4. for (let i = 0; i < arr.length; i ++) {
  5. if (arr[i] === n) {
  6. return true
  7. }
  8. }
  9. return false
  10. }
  11. // good
  12. let arr = [1, 3, 5, 7]
  13. let isHasNum = n => arr.some(num => num === n)
  14. // best
  15. let arr = [1, 3, 5, 7]
  16. let isHasNum = (n, arr) => arr.some(num => num === n)

6、使用forEach方法遍历数组,不形成新数组

  1. // bad
  2. for (let i = 0; i < arr.length; i ++) {
  3. // todo
  4. arr[i].key = balabala
  5. }
  6. // good
  7. arr.forEach(item => {
  8. // todo
  9. item.key = balabala
  10. })

7、使用filter方法过滤原数组,形成新数组

  1. // bad
  2. let arr = [1, 3, 5, 7],
  3. newArr = []
  4. for (let i = 0; i < arr.length; i ++) {
  5. if (arr[i] > 4) {
  6. newArr.push(arr[i])
  7. }
  8. }
  9. // good
  10. let arr = [1, 3, 5, 7]
  11. let newArr = arr.filter(n => n > 4) // [5, 7]

8、使用map对数组中所有元素批量处理,形成新数组

  1. // bad
  2. let arr = [1, 3, 5, 7],
  3. newArr = []
  4. for (let i = 0; i < arr.length; i ++) {
  5. newArr.push(arr[i] + 1)
  6. }
  7. // good
  8. let arr = [1, 3, 5, 7]
  9. let newArr = arr.map(n => n + 1) // [2, 4, 6, 8]
  1. let a = [{id:1}, {id:2}, {id:3},{id:4}]
  2. let ids = a.map(n => n.id).toString()
  3. 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

  1. <a name="tjxfb"></a>
  2. ### 10、Object.values/Object.keys快速获取对象键名和键值
  3. ```json
  4. /*使用Object.values快速获取对象键值*/
  5. // bad
  6. let keys = []
  7. for (value in obj) {
  8. keys.push(value)
  9. }
  10. // good
  11. Object.keys(obj);
  12. (3) ["a", "b", "c"]
  1. /*使用Object.keys快速获取对象键名*/
  2. // bad
  3. let values = []
  4. for (key in obj) {
  5. values.push(obj[key])
  6. }
  7. // good
  8. Object.values(obj);
  9. (3) [1, 2, 3]
  • 巧用解构简化代码

11、解构数组进行变量值的替换

  1. // bad
  2. let a = 1,
  3. b = 2
  4. let temp = a
  5. a = b
  6. b = temp
  7. // good
  8. let a = 1,
  9. b = 2
  10. [b, a] = [a, b]

12、解构对象

  1. // bad
  2. setForm (person) {
  3. this.name = person.name
  4. this.age = person.age
  5. }
  6. // good
  7. setForm ({name, age}) {
  8. this.name = name
  9. this.age = age
  10. }
  1. // bad
  2. const obj = {
  3. a:1,
  4. b:2,
  5. c:3,
  6. d:4,
  7. e:5,
  8. }
  9. const a = obj.a;
  10. const b = obj.b;
  11. const c = obj.c;
  12. const d = obj.d;
  13. const e = obj.e;
  14. const f = obj.a + obj.d;
  15. const g = obj.c + obj.e;
  16. //good
  17. const {a,b,c,d,e} = obj;
  18. const f = a + d;
  19. const g = c + e;
  • 如果想创建的变量名和对象的属性名不一致,可以这么写:(a的值赋值给a1属性名)
  1. const {a:a1} = obj;
  2. console.log(a1);// 1
  • ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
  1. const {a,b,c,d,e} = obj || {};

13、解构时重命名简化命名

  • 有的后端返回的键名特别长,你可以这样干
  1. // bad
  2. setForm (data) {
  3. this.one = data.aaa_bbb_ccc_ddd
  4. this.two = data.eee_fff_ggg
  5. }
  6. // good
  7. setForm ({aaa_bbb_ccc_ddd, eee_fff_ggg}) {
  8. this.one = aaa_bbb_ccc_ddd
  9. this.two = eee_fff_ggg
  10. }
  11. // best
  12. setForm ({aaa_bbb_ccc_ddd: one, eee_fff_ggg: two}) {
  13. this.one = one
  14. this.two = two
  15. }

14、解构时设置默认值

  1. // bad
  2. setForm ({name, age}) {
  3. if (!age) age = 16
  4. this.name = name
  5. this.age = age
  6. }
  7. // good
  8. setForm ({name, age = 16}) {
  9. this.name = name
  10. this.age = age
  11. }

15、|| 短路符设置默认值

  1. let person = {
  2. name: '张三',
  3. age: 38
  4. }
  5. let name = person.name || '佚名'

16、字符串拼接使用 ${}

  1. let person = {
  2. name: 'LiMing',
  3. age: 18
  4. }
  5. // bad
  6. function sayHi (obj) {
  7. console.log('大家好,我叫' + person.name = ',我今年' + person.age + '了')
  8. }
  9. // good
  10. function sayHi (person) {
  11. console.log(`大家好,我叫${person.name},我今年${person.age}了`)
  12. }
  13. // best
  14. function sayHi ({name, age}) {
  15. console.log(`大家好,我叫${name},我今年${age}了`)
  16. }

17、处理多个条件

  1. // bad
  2. const conditions = ["Condition 2","Condition String2"];
  3. someFunction(str){
  4. if(str.includes("someValue1") || str.includes("someValue2")){
  5. return true
  6. }else{
  7. return false
  8. }
  9. }
  10. // good
  11. someFunction(str){
  12. const conditions = ["someValue1","someValue2"];
  13. return conditions.some(condition=>str.includes(condition));
  14. }

18、使用find()在数组中查找指定对象

  • JavaScript find() 方法可用于搜索数组以查找特定对象。
  • 如果是精确搜索用ES6中的find,性能优化,find方法中找到符合条件的项,就不会继续遍历数组。
  • 模糊搜索一般用filter来实现
  1. // bad
  2. const employess = [
  3. {name: "Paul", job_title: "Software Engineer"},
  4. {name: "Peter", job_title: "Web Developer"},
  5. {name: "Harald", job_title: "Screen Designer"},
  6. ];
  7. for (let i = 0; i < employess.length; i++) {
  8. if(employess[i].job_title === "Software Engineer"){
  9. let sen = employess[i];
  10. }
  11. }
  12. //good
  13. const employess = [
  14. {name: "Paul", job_title: "Software Engineer"},
  15. {name: "Peter", job_title: "Web Developer"},
  16. {name: "Harald", job_title: "Screen Designer"},
  17. ]
  18. let sen = employess.find(data => data.job_title === "Software Engineer")
  19. console.log(sen) // { name: 'Paul', job_title: 'Software Engineer' }
  • findIndex查找对象在数组中的位置

19、数组/对象合并数据(数组去重)

  1. //bad
  2. const a = [1,2,3];
  3. const b = [1,5,6];
  4. const c = a.concat(b);//[1,2,3,1,5,6]
  5. const obj1 = {
  6. a:1,
  7. }
  8. const obj2 = {
  9. b:1,
  10. }
  11. const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}
  12. //good
  13. const a = [1,2,3];
  14. const b = [1,5,6];
  15. const c = [...new Set([...a,...b])];//[1,2,3,5,6]
  16. const obj1 = {
  17. a:1,
  18. }
  19. const obj2 = {
  20. b:1,
  21. }
  22. const obj = {...obj1,...obj2};//{a:1,b:1}

20、空值合并运算符

  • 空值合并运算符 (??) 是一个逻辑运算符
  • 当其左侧操作数为空(null)或未定义(undefined)时返回其右侧操作数
  1. const foo = null ?? 'default string';
  2. const baz = 0 ?? 42;
  3. console.log(foo); // default string
  4. console.log(baz); // 0

21、拼接字符串(字符串模板多条件处理)

  • 在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
  1. //bad
  2. const name = '小明';
  3. const score = 59;
  4. let result = '';
  5. if(score > 60){
  6. result = `${name}的考试成绩及格`;
  7. }else{
  8. result = `${name}的考试成绩不及格`;
  9. }
  10. //good
  11. const name = '小明';
  12. const score = 59;
  13. const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;

22、flat多维数组转一维数组(扁平化数组)

  • 一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中
  1. const deps = {
  2. '采购部':[1,2,3],
  3. '人事部':[5,8,12],
  4. '行政部':[5,14,79],
  5. '运输部':[3,64,105],
  6. }
  7. let member = [];
  8. for (let item in deps){
  9. const value = deps[item];
  10. if(Array.isArray(value)){
  11. member = [...member,...value]
  12. }
  13. }
  14. member = [...new Set(member)]
  • 用Object.values来获取对象的全部属性值
  • 数组的扁平化处理用ES6提供的flat方法来处理(多层嵌套for循环需要循环嵌套)
  1. const deps = {
  2. '采购部':[1,2,3],
  3. '人事部':[5,8,12],
  4. '行政部':[5,14,79],
  5. '运输部':[3,64,105],
  6. }
  7. let member = Object.values(deps).flat(Infinity);
  • flat方法不支持IE浏览器。
  • flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。
  1. [1, 2, [3, 4]].flat()
  2. // [1, 2, 3, 4]
  1. [1, 2, [3, [4, 5]]].flat()
  2. // [1, 2, 3, [4, 5]]
  3. [1, 2, [3, [4, 5]]].flat(2)
  4. // [1, 2, 3, 4, 5]
  • 如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数
  1. [1, [2, [3]]].flat(Infinity)
  2. // [1, 2, 3]

23、.?可选链运算符(访问深层嵌套的属性-将键名变成可选)

  • 我们有时候为了访问深层嵌套的属性,一不小心就会报undefined的错,需要写一个很长的&&链去检查每个属性是否存在,代码如下
  • 业务代码中经常会遇到这样的情况,a对象有个属性b,b也是一个对象有个属性c,
  • 我们需要访问c,经常会写成a.b.c,但是如果f不存在时,就会出错
  1. const a = {
  2. b: {
  3. c: 123,
  4. }
  5. }
  6. console.log(a.b.c); // 123;
  7. console.log(a.f.c); // f不存在所以会报错
  • ECMAScript2020定义可选链运算符解决该问题,通过在.之前添加一个?将键名变成可选
  1. let person = {};
  2. console.log(person?.profile?.age ?? 18); // 18
  • 可选链运算符
  1. let age = getUserInfo?.().data?.info?.age;

24、异步函数

  • 异步函数很常见,经常是用 Promise 来实现
  1. //bad
  2. const fn1 = () =>{
  3. return new Promise((resolve, reject) => {
  4. setTimeout(() => {
  5. resolve(1);
  6. }, 300);
  7. });
  8. }
  9. const fn2 = () =>{
  10. return new Promise((resolve, reject) => {
  11. setTimeout(() => {
  12. resolve(2);
  13. }, 600);
  14. });
  15. }
  16. const fn = () =>{
  17. fn1().then(res1 =>{
  18. console.log(res1);// 1
  19. fn2().then(res2 =>{
  20. console.log(res2)
  21. })
  22. })
  23. }
  24. // good
  25. const fn = async () =>{
  26. const res1 = await fn1();
  27. const res2 = await fn2();
  28. console.log(res1);// 1
  29. console.log(res2);// 2
  30. }
  • 但是要做并发请求时,还是要用到Promise.all()。
  1. const fn = () =>{
  2. Promise.all([fn1(),fn2()]).then(res =>{
  3. console.log(res);// [1,2]
  4. })
  5. }
  • 如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。

25、对象属性简写

  1. //bad
  2. const obj = { x:x, y:y };
  3. //good
  4. const obj = { x, y };

26、!! 将任何值转换为布尔值(除了false/0/“”)

  1. !!true // true
  2. !!2 // true
  3. !![] // true
  4. !!"Test" // true
  5. !!false // false
  6. !!0 // false
  7. !!"" // false
  • !!常常用来做类型判断,在第一步!(变量)之后再做逻辑取反运算,在js中新手常常会写这样臃肿的代码:
  • 判断变量a为非空,未定义或者非空串才能执行方法体的内容。
  1. //bad
  2. let a;
  3. if( a != null && a != '' && typeof(a) != undefined ){
  4. //执行代码
  5. }
  6. //good
  7. if( !!a ){
  8. //执行代码
  9. }

27、reduce计算元素的总和

  • 现在,我们将介绍它们之父,全能的 reduce 函数,您可以使用它编写自己的 map 、 filter 以及所有其他 Array 函数。
  • reduce 方法包括将元素数组减少为单个值。它需要两个参数:
  • 一个函数,它的第一个参数 previousValue 是到目前为止累积的值,
  • 第二个参数 currentValue 是我们在这个数组中检查的当前值。它必须返回新的累加值。
  • 一个初始值。在第一次迭代中,该值将用作previousValue
  1. const elements = [1, 2, 3, 4, 5];
  2. const nextElements = elements.reduce(
  3. (previousValue, currentValue) => previousValue + currentValue,
  4. 0
  5. ); // 15
  • 这种方法只是将元素简化为其组成部分的总和。它本质上是添加它们,一次一个元素。
  • 您是否注意到传递给 reduce 方法的函数有多简单?这是一个简单的总和!让我们将其重构为纯函数。
  1. const elements = [1, 2, 3, 4, 5];
  2. const sum = (a, b) => a + b;
  3. const nextElements = elements.reduce(sum, 0); // 15
  • 这段代码的美妙之处在于它的可读性。您可以从字面上阅读它的作用:它将元素减少到它们的总和。
  • 现在,我们已经对使用虚拟示例的 reduce 方法有了很好的理解,我们可以使用它来计算所有用户余额的总和。
  1. const users = [
  2. {
  3. name: "Jane",
  4. balance: 100,
  5. },
  6. {
  7. name: "John",
  8. balance: 75,
  9. },
  10. {
  11. name: "Ellis",
  12. balance: 31.3,
  13. },
  14. ];
  15. const addBalance = (balance, user) => balance + user.balance;
  16. 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

  1. <a name="YysiP"></a>
  2. ### 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)
  3. ```json
  4. /* 必须是二维数组 */
  5. const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
  6. const obj = Object.fromEntries(arr);
  7. console.log(obj); // { 0: "a", 1: "b", 2: "c" }