20個(gè)提升效率的JS簡(jiǎn)寫(xiě)技巧,告別無(wú)奈!
JavaScript 中有很多簡(jiǎn)寫(xiě)技巧,可以縮短代碼長(zhǎng)度、減少冗余,并且提高代碼的可讀性和可維護(hù)性。本文將介紹 20 個(gè)提升效率的 JS 簡(jiǎn)寫(xiě)技巧,助你告別屎山,輕松編寫(xiě)優(yōu)雅的代碼!
移除數(shù)組假值
可以使用 filter() 結(jié)合 Boolean 來(lái)簡(jiǎn)化移除數(shù)組假值操作。假值指的是在條件判斷中被視為 false 的值,例如 null、undefined、空字符串("" 或 '')、0、NaN 和 false。
傳統(tǒng)寫(xiě)法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];
let filterArray = arr.filter(value => {
    if(value) {
      return value
    };
}); 
// [12, 'xyz', -25, 0.5]簡(jiǎn)化寫(xiě)法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];
let filterArray = arr.filter(value => Boolean(value)); // [12, 'xyz', -25, 0.5]更簡(jiǎn)化寫(xiě)法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];
let filterArray = arr.filter(Boolean); // [12, 'xyz', -25, 0.5]Boolean 是 JavaScript 的內(nèi)置構(gòu)造函數(shù),通過(guò)傳遞一個(gè)值給它,可以將該值轉(zhuǎn)換為布爾值。在這種情況下,Boolean 構(gòu)造函數(shù)作為回調(diào)函數(shù)傳遞給 filter() 方法,因此會(huì)將每個(gè)數(shù)組元素轉(zhuǎn)換為布爾值。只有轉(zhuǎn)換結(jié)果為真值的元素才會(huì)保留在新數(shù)組中。
注意:這種方式會(huì)將 0 也過(guò)濾掉,如果不需要過(guò)濾 0,需要進(jìn)行額外的判斷。
數(shù)組查找
當(dāng)對(duì)數(shù)組進(jìn)行查找時(shí),indexOf()用于獲取查找項(xiàng)的位置。如果未找到該項(xiàng),則返回值為-1。在JavaScript中,0被視為false,而大于或小于0的數(shù)字被視為true。因此,需要這樣來(lái)寫(xiě):
傳統(tǒng)寫(xiě)法:
if(arr.indexOf(item) > -1) { 
}
if(arr.indexOf(item) === -1) {
}簡(jiǎn)化寫(xiě)法:
if(~arr.indexOf(item)) {
}
if(!~arr.indexOf(item)) {
}位非(~)運(yùn)算符對(duì)除了-1之外的任何值都返回一個(gè)"真"值。對(duì)其進(jìn)行取反就是簡(jiǎn)單地使用!~即可。另外,也可以使用includes()函數(shù):
if(arr.includes(item)) {
}空值合并運(yùn)算符
空值合并運(yùn)算符(??)用于為 null 或 undefined 的變量提供默認(rèn)值。
傳統(tǒng)寫(xiě)法:
const fetchUserData = () => {
	return '前端充電寶';
};
const data = fetchUserData();
const username = data !== null && data !== undefined ? data : 'Guest';簡(jiǎn)化寫(xiě)法:
const fetchUserData = () => {
	return '前端充電寶';
};
const data = fetchUserData();
const username = data ?? 'CUGGZ';除此之外,還有一個(gè)空位合并賦值運(yùn)算符(??=),用于在變量為空(null 或 undefined)時(shí)進(jìn)行賦值操作。
傳統(tǒng)寫(xiě)法:
let variable1 = null;
let variable2 = "前端充電寶";
if (variable1 === null || variable1 === undefined) {
  variable1 = variable2;
}簡(jiǎn)化寫(xiě)法:
let variable1 = null;
let variable2 = "前端充電寶";
variable1 ??= variable2;??= 的寫(xiě)法更加簡(jiǎn)潔和易讀。它首先檢查變量 variable1 是否為 null 或 undefined,如果是,則將它賦值為 variable2 的值。如果 variable1 已經(jīng)有一個(gè)非空的值,那么賦值操作就不會(huì)發(fā)生。
邏輯或賦值運(yùn)算符
邏輯或賦值運(yùn)算符(||=)用于為變量分配默認(rèn)值。
傳統(tǒng)寫(xiě)法:
let count;
if (!count) {
  count = 0;
}簡(jiǎn)化寫(xiě)法:
let count;
count ||= 0;當(dāng) count 為假值(例如 undefined、null、false、0、NaN 或空字符串)時(shí),邏輯或賦值運(yùn)算符將 count 賦值為 0。否則,它會(huì)保留 count 的原始值。
多值匹配
對(duì)于多個(gè)值的匹配,可以將所有的值放入一個(gè)數(shù)組中,然后使用 indexOf() 方法進(jìn)行檢查。indexOf() 方法是 JavaScript 數(shù)組的一個(gè)內(nèi)置方法,它用于返回指定元素在數(shù)組中第一次出現(xiàn)的位置索引。如果數(shù)組中不存在該元素,則返回 -1。
傳統(tǒng)寫(xiě)法:
if (value === 1 || value === 'one' || value === 2 || value === 'two') {
  // ...
}簡(jiǎn)化寫(xiě)法:
if ([1, 'one', 2, 'two'].indexOf(value) >= 0) {
   // ...
}更簡(jiǎn)化寫(xiě)法:
if ([1, 'one', 2, 'two'].includes(value)) { 
    // ...
}三元表達(dá)式
使用三元表達(dá)式表示可以簡(jiǎn)化if...else。
傳統(tǒng)寫(xiě)法:
let isAdmin;
if (user.role === 'admin') {
  isAdmin = true;
} else {
  isAdmin = false;
}簡(jiǎn)化寫(xiě)法:
const isAdmin = user.role === 'admin' ? true : false;更簡(jiǎn)化寫(xiě)法:
const isAdmin = user.role === 'admin';短路求值
當(dāng)將一個(gè)變量的值賦給另一個(gè)變量時(shí),可能希望確保源變量不為 null、undefined 或空??梢跃帉?xiě)一個(gè)包含多個(gè)條件的長(zhǎng) if 語(yǔ)句,或者使用短路求值來(lái)簡(jiǎn)化。
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
    let variable2 = variable1;
}使用短路求值簡(jiǎn)化后的代碼如下:
const variable2 = variable1 || 'new';對(duì)于邏輯或(||)操作符,以下值被視為假:
- false
 - 0
 - 空字符串("" 或 '')
 - null
 - undefined
 - NaN
 
所以,如果本身的值可能就是這些中的一個(gè),就不適合使用短路求值。
短路求值還能在函數(shù)調(diào)用中避免不必要的函數(shù)執(zhí)行。
傳統(tǒng)寫(xiě)法:
function fetchData() {
  if (shouldFetchData) {
    return fetchDataFromAPI();
  } else {
    return null;
  }
}簡(jiǎn)化寫(xiě)法:
function fetchData() {
  return shouldFetchData && fetchDataFromAPI();
}當(dāng) shouldFetchData 為真值時(shí),短路求值會(huì)繼續(xù)執(zhí)行 fetchDataFromAPI() 函數(shù)并返回其結(jié)果。如果 shouldFetchData 為假值,短路求值會(huì)直接返回假值(null),避免了不必要的函數(shù)調(diào)用。
科學(xué)計(jì)數(shù)法
可以使用科學(xué)技術(shù)法來(lái)表示數(shù)字,以省略尾部的零。例如,1e7 實(shí)際上表示 1 后面跟著 7 個(gè)零。它表示一個(gè)十進(jìn)制,相當(dāng)于 10,000,000。
傳統(tǒng)寫(xiě)法:
for (let i = 0; i < 10000; i++) {}簡(jiǎn)化寫(xiě)法:
for (let i = 0; i < 1e7; i++) {}
// 下面的所有比較都將返回 true
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;位運(yùn)算符
雙位非運(yùn)算符有一個(gè)非常實(shí)用的用途,可以用它來(lái)替代Math.floor()函數(shù),它在執(zhí)行相同的操作時(shí)速度更快。
傳統(tǒng)寫(xiě)法:
Math.floor(4.9) === 4  //true簡(jiǎn)化寫(xiě)法:
~~4.9 === 4  //true指數(shù)冪運(yùn)算
指數(shù)冪運(yùn)算可以使用 ** 來(lái)簡(jiǎn)化。
傳統(tǒng)寫(xiě)法:
Math.pow(2,3); // 8
Math.pow(2,2); // 4
Math.pow(4,3); // 64簡(jiǎn)化寫(xiě)法:
2**3 // 8
2**4 // 4
4**3 // 64從 ES7(ECMAScript 2016)開(kāi)始,JavaScript 引入了指數(shù)冪運(yùn)算符 **,使指數(shù)冪運(yùn)算更加簡(jiǎn)潔。
雙非未運(yùn)算符
在 JavaScript 中,雙非位運(yùn)算符 ~~ 可以用于將數(shù)字向下取整,類似于 Math.floor() 方法的功能。
傳統(tǒng)寫(xiě)法:
const floor = Math.floor(6.8); // 6簡(jiǎn)化寫(xiě)法:
const floor = ~~6.8; // 6注意:雙非位運(yùn)算符只適用于 32 位整數(shù),即范圍為 -(2^31) 到 (2^31)-1,即 -2147483648 到 2147483647。對(duì)于大于 2147483647 或小于 0 的數(shù)字,雙非位運(yùn)算符(~~)會(huì)給出錯(cuò)誤的結(jié)果,因此建議在這種情況下使用 Math.floor() 方法。
對(duì)象屬性
ES6 提供了一種更簡(jiǎn)潔的方式來(lái)給對(duì)象賦值屬性。如果變量名與對(duì)象的鍵名相同,可以利用簡(jiǎn)寫(xiě)符號(hào)來(lái)進(jìn)行賦值。
傳統(tǒng)寫(xiě)法:
const name = '微信公眾號(hào):前端充電寶';
const age = 18;
const person = {
  name: name,
  age: age
};簡(jiǎn)化寫(xiě)法:
const name = '微信公眾號(hào):前端充電寶';
const age = 30;
const person = {
  name,
  age
};箭頭函數(shù)
箭頭函數(shù)可以簡(jiǎn)化經(jīng)典函數(shù)的寫(xiě)法。
傳統(tǒng)寫(xiě)法:
function sayHello(name) {
  console.log('Hello', name);
}
setTimeout(function() {
  console.log('Loaded')
}, 2000);
list.forEach(function(item) {
  console.log(item);
});簡(jiǎn)化寫(xiě)法:
sayHello = name => console.log('Hello', name);
setTimeout(() => console.log('Loaded'), 2000);
list.forEach(item => console.log(item));如果箭頭函數(shù)只有一條語(yǔ)句,它會(huì)隱式地返回其求值的結(jié)果,這時(shí)可以省略 return 關(guān)鍵字:
傳統(tǒng)寫(xiě)法:
function calcCircumference(diameter) {
  return Math.PI * diameter
}簡(jiǎn)化寫(xiě)法:
calcCircumference = diameter => (
  Math.PI * diameter;
)參數(shù)解構(gòu)
如果正在使用一些流行的 Web 框架,比如 React、Vue,可能會(huì)使用數(shù)組或?qū)ο笞置媪啃问降臄?shù)據(jù)來(lái)在組件之間傳遞信息。在組件中要想使用數(shù)據(jù)對(duì)象,就需要對(duì)其進(jìn)行解構(gòu)。
傳統(tǒng)寫(xiě)法:
const observable = require('mobx/observable');
const action = require('mobx/action');
const runInAction = require('mobx/runInAction');
const store = this.props.store;
const form = this.props.form;
const loading = this.props.loading;
const errors = this.props.errors;
const entity = this.props.entity;簡(jiǎn)化寫(xiě)法:
import { observable, action, runInAction } from 'mobx';
const { store, form, loading, errors, entity } = this.props;還可以為變量賦予新的變量名:
const { store, form, loading, errors, entity:contact } = this.props;擴(kuò)展運(yùn)算符
在ES6中引入的擴(kuò)展運(yùn)算符可以簡(jiǎn)化數(shù)組和對(duì)象的一些操作。
傳統(tǒng)寫(xiě)法:
// 合并數(shù)組
const odd = [1, 3, 5];
const nums = [2, 4, 6].concat(odd);
// 克隆數(shù)組
const arr = [1, 2, 3, 4];
const arr2 = arr.slice();簡(jiǎn)化寫(xiě)法:
// 合并數(shù)組
const odd = [1, 3, 5];
const nums = [2, 4, 6, ...odd];
console.log(nums); // [ 2, 4, 6, 1, 3, 5 ]
// 克隆數(shù)組
const arr = [1, 2, 3, 4];
const arr2 = [...arr];與 concat() 函數(shù)不同,可以使用擴(kuò)展運(yùn)算符在另一個(gè)數(shù)組的任意位置插入一個(gè)數(shù)組。
const odd = [1, 3, 5];
const nums = [2, ...odd, 4, 6];還可以將擴(kuò)展運(yùn)算符與ES6的解構(gòu)語(yǔ)法結(jié)合使用:
const { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a) // 1
console.log(b) // 2
console.log(z) // { c: 3, d: 4 }擴(kuò)展運(yùn)算符還能用于合并對(duì)象:
傳統(tǒng)寫(xiě)法:
let fname = { firstName : '前端' };
let lname = { lastName : '充電寶'}
let full_names = Object.assign(fname, lname);簡(jiǎn)化寫(xiě)法:
let full_names = {...fname, ...lname};強(qiáng)制參數(shù)
在傳統(tǒng)的 JavaScript 寫(xiě)法中,為了確保函數(shù)參數(shù)被傳入一個(gè)有效值,我們需要使用條件語(yǔ)句來(lái)拋出一個(gè)錯(cuò)誤。可以通過(guò)使用強(qiáng)制參數(shù)簡(jiǎn)寫(xiě)的寫(xiě)法實(shí)現(xiàn)相同的邏輯。
傳統(tǒng)寫(xiě)法:
function foo(bar) {
  if(bar === undefined) {
    throw new Error('Missing parameter!');
  }
  return bar;
}簡(jiǎn)化寫(xiě)法:
mandatory = () => {
  throw new Error('Missing parameter!');
}
foo = (bar = mandatory()) => {
  return bar;
}這里定義了一個(gè)名為 mandatory 的函數(shù),用于拋出一個(gè)錯(cuò)誤,表示函數(shù)參數(shù)未被傳入。然后,在函數(shù) foo 的參數(shù)列表中,使用賦默認(rèn)值的方式來(lái)將 bar 參數(shù)設(shè)置為 mandatory() 的調(diào)用結(jié)果,如果 bar 參數(shù)未被傳入或者傳入了假值,就會(huì)觸發(fā) mandatory() 函數(shù)的執(zhí)行。
轉(zhuǎn)為布爾值
可以使用雙重邏輯非操作符將任何值轉(zhuǎn)換為布爾值。
!!23 // TRUE
!!"" // FALSE
!!0 // FALSE
!!{} // TRUE單一的邏輯非操作符已經(jīng)可以將值轉(zhuǎn)換為布爾類型并對(duì)其進(jìn)行取反,所以第二個(gè)邏輯非操作符會(huì)再次對(duì)其進(jìn)行取反,從而將其恢復(fù)為原始含義,并保持為布爾類型。
變量交換
可以使用數(shù)組解構(gòu)來(lái)輕松實(shí)現(xiàn)變量交換。
傳統(tǒng)寫(xiě)法(使用臨時(shí)變量完成兩個(gè)變量的交換):
let a = 5;
let b = 10;
const temp = a;
a = b;
b = temp;簡(jiǎn)化寫(xiě)法(使用數(shù)組解構(gòu)賦值完成兩個(gè)變量交換):
let a = 5;
let b = 10;
[a, b] = [b, a];這里創(chuàng)建了一個(gè)包含兩個(gè)元素的數(shù)組 [b, a],然后使用數(shù)組解構(gòu)賦值將其中的值分別賦給變量 a 和 b。由于左側(cè)的數(shù)組和右側(cè)的數(shù)組結(jié)構(gòu)相同,所以兩個(gè)值會(huì)進(jìn)行交換。
變量聲明
當(dāng)需要同時(shí)聲明多個(gè)變量時(shí),可以使用變量聲明的簡(jiǎn)寫(xiě)方法來(lái)節(jié)省時(shí)間和空間。
傳統(tǒng)寫(xiě)法:
let x;
let y;
let z = 3;簡(jiǎn)化寫(xiě)法:
let x, y, z = 3;不過(guò),這個(gè)優(yōu)化有些爭(zhēng)議,很多人認(rèn)為這么寫(xiě)會(huì)影響代碼的可讀性,因?yàn)樵S多變量寫(xiě)到了一行,不如一個(gè)變量一行更清晰明了,所以可以選擇性采用。
如果有多個(gè)變量需要賦相同的值,則可以使用連等來(lái)實(shí)現(xiàn)。
傳統(tǒng)寫(xiě)法:
let a = 100;
let b = 100;
let c = 100;簡(jiǎn)化寫(xiě)法:
let a = b = c = 100;For 循環(huán)
JavaScript 中傳統(tǒng)的 for 循環(huán)語(yǔ)法使用數(shù)組的長(zhǎng)度作為迭代器來(lái)遍歷數(shù)組。還有很多 for 循環(huán)的快捷方式提供了在數(shù)組中迭代對(duì)象的不同方法,例如:
- for...of:用于遍歷內(nèi)置字符串、數(shù)組、類數(shù)組對(duì)象、NodeList。
 - for...in:用于訪問(wèn)數(shù)組的索引和對(duì)對(duì)象字面量進(jìn)行遍歷,并記錄屬性名稱和值的字符串。
 - Array.forEach:使用回調(diào)函數(shù)對(duì)數(shù)組元素及其索引執(zhí)行操作。
 
傳統(tǒng)寫(xiě)法:
for (let i = 0; i < arr.length; i++) {
  console.log("item: ", arr[i]);}
}簡(jiǎn)化寫(xiě)法:
for (let str of arr) {
  console.log("item: ", str);
}
arr.forEach((str) => {
  console.log("item: ", str);
});
for (let index in arr) {
  console.log(index, arr[index]);
}對(duì)于對(duì)象字面量,也可以使用 for...in 來(lái)遍歷:
const obj = { a: 1, b: 3, c: 5 };
for (let key in obj) {
  console.log(key, obj[key]);
}














 
 
 













 
 
 
 