JS優(yōu)化冗余代碼的技巧分享
1. 使用箭頭函數(shù)簡化函數(shù)定義
// 傳統(tǒng)函數(shù)定義 function add(a, b) { return a + b; } // 箭頭函數(shù)簡化 const add = (a, b) => a + b;
2. 使用解構(gòu)賦值簡化變量聲明
// 傳統(tǒng)變量聲明 const firstName = person.firstName; const lastName = person.lastName; // 解構(gòu)賦值簡化 const { firstName, lastName } = person;
3. 使用模板字面量進(jìn)行字符串拼接
// 傳統(tǒng)字符串拼接 const greeting = 'Hello, ' + name + '!'; // 模板字面量簡化 const greeting = `Hello, ${name}!`;
4. 使用展開運(yùn)算符進(jìn)行數(shù)組和對象操作
// 合并數(shù)組 const combined = [...array1, ...array2]; // 復(fù)制對象 const clone = { ...original };
5. 使用數(shù)組的高階方法簡化循環(huán)和數(shù)據(jù)操作
// 遍歷數(shù)組并返回新數(shù)組 const doubled = numbers.map(num => num * 2); // 過濾數(shù)組 const evens = numbers.filter(num => num % 2 === 0);
6. 使用條件運(yùn)算符簡化條件判斷
// 傳統(tǒng)條件判斷 let message; if (isSuccess) { message = 'Operation successful'; } else { message = 'Operation failed'; } // 條件運(yùn)算符簡化 const message = isSuccess ? 'Operation successful' : 'Operation failed';
7. 使用對象解構(gòu)和默認(rèn)參數(shù)簡化函數(shù)參數(shù)
// 傳統(tǒng)參數(shù)設(shè)置默認(rèn)值 function greet(name) { const finalName = name || 'Guest'; console.log(`Hello, ${finalName}!`); } // 對象解構(gòu)和默認(rèn)參數(shù)簡化 function greet({ name = 'Guest' }) { console.log(`Hello, ${name}!`); }
8. 使用函數(shù)式編程概念如純函數(shù)和函數(shù)組合
// 純函數(shù) function add(a, b) { return a + b; } // 函數(shù)組合 const multiplyByTwo = value => value * 2; const addFive = value => value + 5; const result = addFive(multiplyByTwo(3));
9. 使用對象字面量簡化對象的創(chuàng)建和定義
// 傳統(tǒng)對象創(chuàng)建 const person = { firstName: 'John', lastName: 'Doe', age: 30, }; // 對象字面量簡化 const firstName = 'John'; const lastName = 'Doe'; const age = 30; const person = { firstName, lastName, age };
10. 使用適當(dāng)?shù)拿妥⑨寔硖岣叽a可讀性
// 不好的 const x = 10; // 設(shè)置x的值為10 function a(b) { return b * 2; // 返回b的兩倍 } // 好的 const speed = 10; // 設(shè)置速度為10 function double(value) { return value * 2; // 返回輸入值的兩倍
11. 優(yōu)雅的寫條件判斷代碼
簡單的條件判斷邏輯用if else
或者 三元運(yùn)算符, 一眼看過去還能知道說的啥,但是大量的if else
和疊加在一起的三元運(yùn)算符就是接盤俠的噩夢~~~
給大家上一個三元運(yùn)算符疊加的案例,我是真實(shí)在項目中遇到過,cpu直接干爆~~~
<view>{{status===1?'成功': status===2 ? '失敗' : status===3 ? '進(jìn)行中' : '未開始' }}</view>
大概是這樣的,具體的項目代碼不好放在這里,小伙伴們意會就行。
復(fù)雜邏輯推薦使用對象Map寫法,符合人腦的邏輯,可讀性高,看著舒服~~~
1.普通的if else
let txt = ''; if (falg) { txt = "成功" } else { txt = "失敗" }
2.三元運(yùn)算符
let txt = flag ? "成功" : "失敗";
3.多個if else
// param {status} status 活動狀態(tài):1:成功 2:失敗 3:進(jìn)行中 4:未開始 let txt = ''; if (status == 1) { txt = "成功"; } else if (status == 2) { txt = "失敗"; } else if (status == 3) { txt = "進(jìn)行中"; } else { txt = "未開始"; }
4.switch case
let txt = ''; switch (status) { case 1: txt = "成功"; break; case 2: txt = "成功"; break; case 3: txt = "進(jìn)行中"; break; default: txt = "未開始"; }
5.對象寫法
const statusMap = { 1: "成功", 2: "失敗", 3: "進(jìn)行中", 4: "未開始" } //調(diào)用直接 statusMapp[status]
6.Map寫法
const actions = new Map([ [1, "成功"], [2, "失敗"], [3, "進(jìn)行中"], [4, "未開始"] ]) // 調(diào)用直接 actions.get(status)
12. 封裝條件語句
同上,if里的條件越多越不利于接盤俠的維護(hù),不利于人腦的理解,一眼看過去又是一堆邏輯。多個邏輯應(yīng)該化零為整。
//大腦:'別來碰我,讓我靜靜' // 不好的 if (fsm.state === 'fetching' && isEmpty(listNode)) { // ... } // 好的 shouldShowSpinner(fsm, listNode){ return fsm.state === 'fetching' && isEmpty(listNode) } if(shouldShowSpinner(fsm, listNode)){ //...doSomething }
13. 函數(shù)應(yīng)該只做一件事
函數(shù)式寫法推崇柯里化
, 一個函數(shù)一個功能,可拆分可組裝。
// 不好的 function createFile(name, temp) { if (temp) { fs.create(`./temp/${name}`); } else { fs.create(name); } } // 好的 function createFile(name) { fs.create(name); } function createTempFile(name) { createFile(`./temp/${name}`) }
再來一個栗子
函數(shù)要做的事情如下:
遍歷clients數(shù)組
遍歷過程中,通過lookup函數(shù)得到一個新的對象clientRecord
判斷clientRecord對象中isActive函數(shù)返回的是不是true,
isActive函數(shù)返回true,執(zhí)行email函數(shù)并把當(dāng)前成員帶過去
// 不好的 function emailClients(clients) { clients.forEach((client) => { const clientRecord = database.lookup(client); if (clientRecord.isActive()) { email(client); } }); } // 好的 function emailClients(clients) { clients .filter(isClientRecord) .forEach(email) } function isClientRecord(client) { const clientRecord = database.lookup(client); return clientRecord.isActive() }
上面不好的栗子一眼看過去是不是感覺一堆代碼在那,一時半會甚至不想去看了。
好的栗子,是不是邏輯很清晰,易讀。
1.巧用filter函數(shù),把filter的回調(diào)單開一個函數(shù)進(jìn)行條件處理,返回符合條件的數(shù)據(jù)
2.符合條件的數(shù)據(jù)再巧用forEach,執(zhí)行email函數(shù)
14. Object.assign給默認(rèn)對象賦默認(rèn)值
// 不好的 const menuConfig = { title: null, body: 'Bar', buttonText: null, cancellable: true }; function createMenu(config) { config.title = config.title || 'Foo'; config.body = config.body || 'Bar'; config.buttonText = config.buttonText || 'Baz'; config.cancellable = config.cancellable === undefined ? config.cancellable : true; } createMenu(menuConfig); // 好的 const menuConfig = { title: 'Order', buttonText: 'Send', cancellable: true }; function createMenu(config) { Object.assign({ title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: true }, config) } createMenu(menuConfig);
15. 函數(shù)參數(shù)兩個以下最好
說一千道一萬,就是為了優(yōu)雅,就是為了可讀性好。
// 不好的 function createMenu(title, body, buttonText, cancellable) { // ... } // 好的 const menuConfig = { title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: true }; function createMenu(config){ // ... } createMenu(menuConfig)
16. 使用解釋性的變量
省流,用了擴(kuò)展運(yùn)算符,為了可讀性(saveCityZipCode(city, zipCode)
可讀性很好,知道參數(shù)是干嘛的)
// 不好的 const address = 'One Infinite Loop, Cupertino 95014'; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]); // 好的 const address = 'One Infinite Loop, Cupertino 95014'; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; cosnt [, city, zipCode] = address.match(cityZipCodeRegex) || []; saveCityZipCode(city, zipCode)
想對類中的屬性進(jìn)行更多自定義取/增/改的操作時,使用set/get
第一次見這個寫法,不知道是啥意思的小伙伴,把他當(dāng)成vue2中的defineProperty
Object.defineProperty(data1,'age',{ set:function(newAge){ console.log(this.name+'現(xiàn)在'+newAge+'歲') }, get:function(){ return 18; } })
是一個意思,賦值的時候set會被觸發(fā),取值的時候get會被觸發(fā)。
巧用自帶屬性,提升性能。
class BankAccount { constructor(balance = 1000) { this._balance = balance; } // It doesn't have to be prefixed with `get` or `set` to be a //getter/setter set balance(amount) { console.log('set') if (verifyIfAmountCanBeSetted(amount)) { this._balance = amount; } } get balance() { console.log('get') return this._balance; } verifyIfAmountCanBeSetted(val) { // ... } } const bankAccount = new BankAccount(); // Buy shoes... bankAccount.balance -= 100; // Get balance let balance = bankAccount.balance;
17. 讓對象擁有私有成員-通過閉包來實(shí)現(xiàn)
閉包天生就是做私有化的
// 不好的 const Employee = function(name) { this.name = name; }; Employee.prototype.getName = function getName() { return this.name; }; const employee = new Employee('John Doe'); console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe delete employee.name; console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined // 好的 const Employee = function(name){ this.getName = function(){ return name } } const employee = new Employee('John Doe'); console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe delete employee.name; console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined
第一個示例
優(yōu)點(diǎn):
通過原型鏈共享方法,節(jié)省了內(nèi)存空間。所有實(shí)例對象共享同一個 getName
方法,而不是每個實(shí)例對象都創(chuàng)建一個獨(dú)立的方法。
缺點(diǎn):
在構(gòu)造函數(shù)中無法直接定義私有屬性或方法,所有屬性和方法都會被暴露在原型鏈上。
第二個示例
優(yōu)點(diǎn):
可以在構(gòu)造函數(shù)內(nèi)部定義私有屬性和方法,不會暴露在對象的原型鏈上,提供了更好的封裝性。
缺點(diǎn):
每次創(chuàng)建實(shí)例對象時,都會創(chuàng)建一個獨(dú)立的方法,每個實(shí)例對象都有自己的 getName
方法,占用更多的內(nèi)存空間。
18. 使用方法鏈
鏈?zhǔn)綄懛ㄒ彩谴a優(yōu)雅之道的重頭戲。
ps:發(fā)明這個的程序員肯定是后端出身的,這種寫法在PHP的CI框架中見過。
// 不好的 class Car { constructor() { this.make = 'Honda'; this.model = 'Accord'; this.color = 'white'; } setMake(make) { this.make = make; } save() { console.log(this.make, this.model, this.color); } } const car = new Car(); car.setMake('Ford'); car.save(); // 好的 class Car { constructor() { this.make = 'Honda'; this.model = 'Accord'; this.color = 'white'; } setMake(make) { this.make = make; // NOTE: return this是為了用鏈?zhǔn)綄懛? return this; } save() { console.log(this.make, this.model, this.color); // NOTE:return this是為了用鏈?zhǔn)綄懛? return this; } } const car = new Car() .setMake('Ford') .save();
看完上面的這么多栗子,小伙伴的思路是不是清晰了很多,在你們的項目里練練手吧。
以上就是JS優(yōu)化冗余代碼的技巧分享的詳細(xì)內(nèi)容,更多關(guān)于JS優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS script腳本中async和defer區(qū)別詳解
這篇文章主要介紹了JS script腳本中async和defer區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06JavaScript簡單實(shí)現(xiàn)動態(tài)改變HTML內(nèi)容的方法示例
這篇文章主要介紹了JavaScript簡單實(shí)現(xiàn)動態(tài)改變HTML內(nèi)容的方法,結(jié)合實(shí)例形式分析了javascript簡單獲取及修改HTML元素的相關(guān)操作技巧,非常簡單易懂,需要的朋友可以參考下2018-12-12js/jquery遍歷對象和數(shù)組的方法分析【forEach,map與each方法】
這篇文章主要介紹了js/jquery遍歷對象和數(shù)組的方法,結(jié)合實(shí)例形式分析了數(shù)組遍歷的forEach,map與each方法常見使用技巧,需要的朋友可以參考下2019-02-02js實(shí)現(xiàn)股票實(shí)時刷新數(shù)據(jù)案例
下面小編就為大家?guī)硪黄猨s實(shí)現(xiàn)股票實(shí)時刷新數(shù)據(jù)案例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05JavaScript Cookie的讀取和寫入函數(shù)
Cookie的讀取和寫入實(shí)現(xiàn)函數(shù)。2009-12-12