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

