最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
code-review之前端代碼優(yōu)化匯總
  • 所謂無規(guī)矩不成方圓,前端時間在團隊 code-review 中發(fā)現(xiàn),小編 推薦大家可以大致過一遍,形成自己的編碼習慣

本文主要針對一些 JavaScript 進行優(yōu)化,使之更加健壯,可讀性更強,更以維護。

if 判斷的優(yōu)化

1、最簡單的方法:if 判斷

let commodity = {
phone: '手機',
computer: '電腦',
television: '電視',
gameBoy: '游戲機',
}
function price(name) {
if (name === commodity.phone) {
console.log(1999)
} else if (name === commodity.computer) {
console.log(9999)
} else if (name === commodity.television) {
console.log(2999)
} else if (name === commodity.gameBoy) {
console.log(3999)
}
}
price('手機') // 9999

缺點:代碼太長了,維護和閱讀都很不友好

2、好一點的方法:Switch

let commodity = {
phone: '手機',
computer: '電腦',
television: '電視',
gameBoy: '游戲機',
}
const price = (name) => {
switch (name) {
case commodity.phone:
console.log(1999)
break
case commodity.computer:
console.log(9999)
break
case commodity.television:
console.log(2999)
break
case commodity.gameBoy:
console.log(3999)
break
}
}
price('手機') // 9999

3、更優(yōu)的方法: 策略模式

  • 策略模式利用組合、委托和多態(tài)等技術(shù)和思想,可以有效地避免多重條件選擇語句。它提供了對開放—封閉原則的完美支持,將算法封裝在獨立的 strategy 中,使得它們易于切換,易于理解,易于擴展。
const commodity = new Map([
['phone', 1999],
['computer', 9999],
['television', 2999],
['gameBoy', 3999],
])
const price = (name) => {
return commodity.get(name)
}
price('phone') // 1999

includes 的優(yōu)化

includes 是 ES7 新增的 API,與 indexOf 不同的是 includes 直接返回的是 Boolean 值,indexOf 則 返回的索引值, 數(shù)組和字符串都有 includes 方法。

需求:我們來實現(xiàn)一個身份認證方法,通過傳入身份 Id 返回對應的驗證結(jié)果

傳統(tǒng)方法

function verifyIdentity(identityId) {
if (identityId == 1 || identityId == 2 || identityId == 3 || identityId == 4) {
return '你的身份合法,請通行!'
} else {
return '你的身份不合法'
}
}

includes 優(yōu)化

function verifyIdentity(identityId) {
if ([1, 2, 3, 4].includes(identityId)) {
return '你的身份合法,請通行!'
} else {
return '你的身份不合法'
}
}

for 循環(huán)

在 JavaScript 中,我們可以使用 for(), while(), for(in),for(of)幾種循環(huán),事實上,這三種循環(huán)中 for(in) 的效率極差,因為他需要查詢散列鍵,所以應該盡量少用。

for 循環(huán)是最傳統(tǒng)的語句,它以變量 i 作為索引,以跟蹤訪問的位置,對數(shù)組進行操作。

var arr = ['a', 'b', 'c']
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]) //結(jié)果依次a,b,c
}

以上的方法有一個問題:就是當數(shù)組的長度到達百萬級時,arr.length 就要計算一百萬次,這是相當耗性能的。所以可以采用以下方法就行改良。

var arr = ['a', 'b', 'c']
for (var i = 0, length = arr.length; i < length; i++) {
console.log(arr[i]) //結(jié)果依次a,b,c
}

此時 arr.length 只需要計算一次,優(yōu)化了性能。

for-in 一般用來來遍歷對象的屬性的,不過屬性需要 enumerable(可枚舉)才能被讀取到。同時 for-in 也可以遍歷數(shù)組,遍歷數(shù)組的時候遍歷的是數(shù)組的下標值。

var obj = { 0: 'a', 1: 'b', 2: 'c' }
for (var key in obj) {
console.log(key) //結(jié)果為依次為0,1,2
}
var arr = ['a', 'b', 'c']
for (var key in a) {
console.log(key) //結(jié)果為依次為0,1,2
}

for-of 語句看著有點像 for-in 語句,但是和 for-of 語句不同的是它不可以循環(huán)對象,只能循環(huán)數(shù)組。

var arr = ['a', 'b', 'c']
for (var value of arr) {
console.log(value) // 結(jié)果依次為a,b,c
}

for-of 比 for-in 循環(huán)遍歷數(shù)組更好。for-of 只要具有 Iterator 接口的數(shù)據(jù)結(jié)構(gòu),都可以使用它迭代成員。它直接讀取的是鍵值。for-in 需要窮舉對象的所有屬性,包括自定義的添加的屬性也能遍歷到。且 for-in 的 key 是 String 類型,有轉(zhuǎn)換過程,開銷比較大。

所以在開發(fā)過程中循環(huán)數(shù)組盡量避免使用 for-in。

數(shù)組去重

數(shù)組去重是實際開發(fā)處理數(shù)據(jù)中經(jīng)常遇到的,方法有很多,這里就不一一例舉了。

1、最傳統(tǒng)的方法:利用數(shù)組的 indexOf 下標屬性來查詢。

function unique4(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i])
}
}
return newArr
}
console.log(unique4([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]))
// [1, 2, 3, 5, 6, 7, 4]

2、優(yōu)化:利用 ES6 的 Set 方法。

Set 本身是一個構(gòu)造函數(shù),用來生成 Set 數(shù)據(jù)結(jié)構(gòu)。Set 函數(shù)可以接受一個數(shù)組(或者具有 iterable 接口的其他數(shù)據(jù)結(jié)構(gòu))作為參數(shù),用來初始化。Set 對象允許你存儲任何類型的值,無論是原始值或者是對象引用。它類似于數(shù)組,但是成員的值都是唯一的,沒有重復的值。

function unique4(arr) {
return Array.from(new Set(arr)) // 利用Array.from將Set結(jié)構(gòu)轉(zhuǎn)換成數(shù)組
}
console.log(unique4([1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]))
// [1, 2, 3, 5, 6, 7, 4]

箭頭函數(shù)

箭頭函數(shù)表達式的語法比函數(shù)表達式更簡潔。所以在開發(fā)中更推薦使用箭頭函數(shù)。特別是在 vue 項目中,使用箭頭函數(shù)不需要在更 this 重新賦一個變量。

// 使用functions
var arr = [5, 3, 2, 9, 1]
var arrFunc = arr.map(function (x) {
return x * x
})
console.log(arrFunc)
// 使用箭頭函數(shù)
var arr = [5, 3, 2, 9, 1]
var arrFunc = arr.map((x) => x * x)

要注意的是,箭頭函數(shù)不綁定 arguments,取而代之用 rest 參數(shù)…解決。

// 不能使用 arguments
let fun1 = (b) => {
console.log(arguments)
}
fun1(2, 92, 32, 32) // Uncaught ReferenceError: arguments is not defined
// 使用rest 參數(shù)
let fun2 = (...c) => {
console.log(c)
}
fun2(3, 82, 32, 11323) // [3, 82, 32, 11323]

Dom 的創(chuàng)建

創(chuàng)建多個 dom 元素時,先將元素 append 到 DocumentFragment 中,最后統(tǒng)一將 DocumentFragment 添加到頁面。

常規(guī)方法;

for (var i = 0; i < 1000; i++) {
var el = document.createElement('p')
el.innerHTML = i
document.body.appendChild(el)
}

使用 DocumentFragment 優(yōu)化多次 append

var frag = document.createDocumentFragment()
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p')
el.innerHTML = i
frag.appendChild(el)
}
document.body.appendChild(frag)

更優(yōu)的方法:使用一次 innerHTML 賦值代替構(gòu)建 dom 元素

var html = []
for (var i = 0; i < 1000; i++) {
html.push('

' + i + '

')
}
document.body.innerHTML = html.join('')

內(nèi)存泄漏

系統(tǒng)進程不再用到的內(nèi)存,沒有及時釋放,就叫做內(nèi)存泄漏(memory leak)。當內(nèi)存占用越來越高,輕則影響系統(tǒng)性能,重則導致進程崩潰。

引起內(nèi)存泄漏的原因

全局變量

1、未聲明變量或者使用 this 創(chuàng)建的變量(this 的指向是 window)都會引起內(nèi)存泄漏

function fn() {
a = "Actually, I'm a global variable"
}
fn()
function fn() {
this.a = "Actually, I'm a global variable"
}
fn()

解決方法:

  • 避免創(chuàng)建全局變量
  • 使用嚴格模式,在 JavaScript 文件頭部或者函數(shù)的頂部加上 use strict。

2、在 vue 單頁面應用,聲明的全局變量在切換頁面的時候沒有清空


這里是首頁
export default {
mounted() {
window.test = {
// 此處在全局window對象中引用了本頁面的dom對象
name: 'home',
node: document.getElementById('home')
}
}
}

解決方案: 在頁面卸載的時候順便處理掉該引用。

destroyed () {
window.test = null // 頁面卸載的時候解除引用
}

閉包

閉包引起的內(nèi)存泄漏原因:閉包可以維持函數(shù)內(nèi)局部變量,使其得不到釋放。

function fn() {
var a = "I'm a"
return function () {
console.log(a)
}
}

解決:將事件處理函數(shù)定義在外部,解除閉包,或者在定義事件處理函數(shù)的外部函數(shù)中,刪除對 dom 的引用。

定時器或事件監(jiān)聽

由于項目中有些頁面難免會碰到需要定時器或者事件監(jiān)聽。但是在離開當前頁面的時候,定時器如果不及時合理地清除,會造成業(yè)務邏輯混亂甚至應用卡死的情況,這個時就需要清除定時器事件監(jiān)聽,即在頁面卸載(關(guān)閉)的生命周期函數(shù)里,清除定時器。

methods:{
resizeFun () {
this.tableHeight = window.innerHeight - document.getElementById('table').offsetTop - 128
},
setTimer() {
this.timer = setInterval(() => { })
},
clearTimer() {//清除定時器
clearInterval(this.timer)
this.timer = null
}
},
mounted() {
this.setTimer()
window.addEventListener('resize', this.resizeFun)
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeFun)
this.clearTimer()
}

防抖與節(jié)流

在前端開發(fā)的過程中,我們經(jīng)常會需要綁定一些持續(xù)觸發(fā)的事件,如 resize、scroll、mousemove 等等,但有些時候我們并不希望在事件持續(xù)觸發(fā)的過程中那么頻繁地去執(zhí)行函數(shù)。這時候就用到防抖與節(jié)流。

案例 1:遠程搜索時需要通過接口動態(tài)的獲取數(shù)據(jù),若是每次用戶輸入都接口請求,是浪費帶寬和性能的。



上面代碼中,