15个简单实用的JavaScript技巧让你的代码更优雅🍊

2,866 阅读6分钟

前言🍊

作为深度代码洁癖,我们都希望能写出简单高效的代码,让我们的代码看起来更加优雅,让我们抛弃繁杂的代码,一起开启简单的旅程~~

正文🍊

方法参数验证

JavaScript允许你设置参数的默认值。使用此方法,我们可以实施一个巧妙的技巧来验证你的方法参数。

const isRequired = () = >{
    throw new Error('param is required')
}

const print = (num = isRequired()) = >{
    console.log(`printing $ {
        num
    }`)
}

print(2) //printing 2
print() // error
print(null) //printing null

整洁,不是吗?

获取数组唯一值

这里提供获取数组唯一值的方法:

const numbers = ['1','2','1','2','3']
// 使用数组From + Set
const uniques = Array.from(new Set(numbers)); // [ '1', '2', '3' ]
// 使用Spread运算符
const uniquesWithSpreadOperator = [... new Set(numbers)]; // [ '1', '2', '3' ]

给定一个对象数组,如果要获取属性的值而不要重复,则可以执行以下操作。

// 假设您有一个具有以下内容的bills数组:
// 假设您有一个具有以下内容的bills数组:
const bills = [
  {
    date: '2018-01-20',
    amount: '220',
    category: 'Electricity',
  },
  {
    date: '2018-01-20',
    amount: '20',
    category: 'Gas',
  },
  {
    date: '2018-02-20',
    amount: '120',
    category: 'Electricity',
  },
];
const categories = [...new Set(bills.map((bill) => bill.category))]; // [ 'Electricity', 'Gas' ]

从数组中删除虚假值

在某些情况下,你可能想从数组中删除伪造的值。虚假值是JavaScript中的值为FALSE的值。JavaScript中只有六个伪造的值,它们是undefinednullNaN0''false滤除这些虚假值的最简单方法是使用以下函数。

const myArray = ['1', '', null, 2, 'a', 3];
const newArray = myArray.filter(Boolean); // [ '1', 2, 'a', 3 ]

如果要对数组进行一些修改,然后过滤新数组,则可以尝试这样的操作。请记住,原本的myArray保持不变。

const myArray = ['1', '', null, 2, 'a', 3];
const newArray = myArray.map((value) => value + 1).flter(Boolean); // [ '11', '1', 1, 3, 'a1', 4 ]

排序数字数组

JavaScript数组带有内置的sort方法。默认情况下,此sort方法将数组元素转换为字符串,并对其进行字典排序。在对数字数组进行排序时,这可能会导致问题。因此,这里是解决此问题的简单解决方案。

const arr=[1,4,8,2,11,7,3,5];
arr.sort(function (a,b){ return a-b }); // arr = [1,2,3,4,5,7,8,11]

这里提供的功能是将number数组中的两个元素与sort方法进行比较。此功能可帮助我们接收正确的输出。

使用别名进行赋值

如果在解构赋值中,对象中一个key是外面作用域同名,则会发生覆盖。解决的方法是为它设置一个别名

const object = { number: 10 };
const number = 2;
//获取number并将其重命名为otherNumber
const { number: otherNumber } = object;
console.log(otherNumber); // 10

清空数组和填充数组

通过设置数组长度来达到清空数组或截取数组的目的

var entries = [1, 2, 3, 4, 5, 6, 7]; 
console.log(entries.length); // 7  
entries.length = 3;   
console.log(entries.length); // 3  
console.log(entries); // [ 1, 2, 3 ]
entries.length = 0;   
console.log(entries.length); // 0 
console.log(entries); // []

Array.prototype.fill()方法使用静态值填充数组中的指定元素。

// 全部填充
const array = Array(2).fill('hello');
console.log(array); // [ 'hello', 'hello' ]
// 部分填充
const array = Array(6).fill('hello', 2, 4);
console.log(array); // [ <2 empty items>, 'hello', 'hello', <2 empty items> ]
// 替换填充:从开始索引(默认为0)到结束索引(默认为array.length)
// 此方法使用给定数组的所有元素填充相同的值
const array = [1, 2, 3, 4, 5];
array.fill(0, 1, 3); // [ 1, 0, 0, 4, 5 ]

方法属性

在es5的时候你可能这样声明方法:

const math = {
  add: function(a,b) { return a + b; },
  sub: function(a,b) { return a - b; }, 
  multiply: function(a,b) { return a * b; }
}

实际上从ES6以后的全部业务。可以这样声明:

const math = {
  add(a,b) { return a + b; },
  sub(a,b) { return a - b; },
  multiply(a,b) { return a * b; }
}

而无需写成

const math = {
 add: (a, b) => {
    return a + b;
  },
}

数组解构

以下代码:

const array = [1, 2, 3, 4, 5, 6];
const a = array[0];
const c = array[2];

可以用一种更加优雅的方式来完成此操作,如下所示:

const arr = [1,2,3,4,5,6];
const [a, ,c, ...remaining] = arr;
console.log(remaining) // [4,5,6]

替换所有字符串中的单词

为了替换指定字符串的所有实例,可以使用 以下命令:

  1. 使用正则表达式
let str = 'hello world! hello you! Hello Elsy!';
str.replace(new RegExp('hello', 'g'), 'hi'); // hi world! hi you! Hello Elsy!
  1. 使用split()join()函数:
let str = 'hello world! hello you! Hello Elsy!';
str = str.replace(new RegExp('hello', 'g'), 'hi'); // hi world! hi you! Hello Elsy!

es2021中提供了String.replaceAll方法。将完全满足此情况下的需要,替换所有匹配的模式,使我们可以轻松替换子字符串,而无需使用RegEx

const str = 'I like my dog, my dog loves me';
const newStr = str.replaceAll('dog', 'cat'); // "I like my cat, my cat loves me"

数组项的对象分解

规范:ECMAScript 2015(第6版,ECMA-262)。通过对象分解将数组项分配给各个变量

const csvString = 'A team,Alabama,US,Hannibal Smith,New York,1000';
const { 3: name, 4: country, 0: team } = csvString.split(',');
console.log(name); //"Hannibal Smith"
console.log(country); //"New York"
console.log(team); //"A Team"

!!操作符

使用!!转换为布尔值,有时,我们需要检查变量是否存在或是否具有有效值,以将其视为真实值。对于这种验证,可以使用!!(双重否定运算符)。一个简单的!!variable,这将任何类型的数据自动转换为布尔和这个变量将返回false唯一的,如果是:0null""undefined,或NaN返回false,否则,它会返回true。

要在实践中理解它,请看以下简单示例:

function Account(cash) {
  this.cash = cash;
  this.hasMoney = !!cash;
}

const account = new Account(100.5);
console.log(account.cash); // 100.50
console.log(account.hasMoney); // true

const emptyAccount = new Account(0);
console.log(emptyAccount.cash); // 0
console.log(emptyAccount.hasMoney); // false

在这种情况下,如果account.cash值大于零,account.hasMoney则将为true

将NodeList转换成Arrays

如果运行该document.querySelectorAll("p")函数,则可能会返回DOM元素数组,即NodeList对象。但这种对象不具有所有阵列的功能,如:sort()reduce()map()filter()。要启用这些以及许多其他本机数组功能,您需要将转换NodeListArrays。要运行此技术,只需使用以下功能[].slice.call(elements)

var elements = document.querySelectorAll("p"); // NodeList
var arrayElements = [].slice.call(elements); // 转换成数组
// 另一种方式
var arrayElements = Array.from(elements);

获取for-of循环中的迭代索引

我们可以entries使用数组的方法获得for-of循环的迭代索引。 然后,我们可以将其与解构任务结合起来。 例如,我们可以这样写:

for (const [i, v] of ['foo', 'bar', 'baz'].entries()) {
  console.log(i, v);
}
// i是索引,v是值。

reduce()的使用

附上一个很详细的链接,这里不再赘述reduce()方法详解及高级技巧

配合使用

最后附上一个我自己写的深拷贝,综合了数组的几个方法,来巩固一下上面的知识

const deepMapKeys = (obj) => {
  return Array.isArray(obj)
    ? obj.map((item) => deepMapKeys(item))
    : typeof obj === 'object'
    ? Object.entries(obj).reduce((current, [key, val]) => {
        current[key] = val !== null && typeof val === 'object' ? deepMapKeys(val) : val;
        return current;
      }, {})
    : obj;
};

const obj = {
  foo: '1',
  nested: {
    child: {
      withArray: [
        {
          grandChild: ['hello'],
        },
      ],
    },
  },
};
const upperKeysObj = deepMapKeys(obj);
upperKeysObj.foo = '2';
upperKeysObj.nested.child.withArray = [1];
console.log(obj); //{ foo: '1', nested: { child: { withArray: [Array] } } }
console.log(upperKeysObj); // { foo: '2', nested: { child: { withArray: [Array] } } }