日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Javascript代码优化的8个知识点

發(fā)布時間:2025/3/19 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Javascript代码优化的8个知识点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本篇文章給大家分享了關(guān)Javascript代碼優(yōu)化的8點總結(jié)

松耦合

當(dāng)修改一個組件而不需要更改其他組件時,就做到了松耦合
1、將JS從CSS中抽離:不要使用CSS表達式

HTML復(fù)制全屏

//不好的做法

.box{width: expression(document.body.offsetWidth + ‘px’)}
2、將CSS從JS中抽離:通過JS修改CSS樣式時,使用className或classList,不要逐條修改style樣式
(1).

HTML復(fù)制全屏

//不好的做法一

ele.style.color = ‘red’;

ele.style.left= ‘10px’;

//不好的做法二

ele.style.cssText =‘color:red;left:10px;’;
(2).

HTML復(fù)制全屏

.reveal{color:red;left:10px;}

//好的做法一

ele.className += ‘reveal’;

//好的做法二

ele.classList.add(‘reveal’);

3、將JS從HTML中抽離:從JS文件放入外置文件中
4、將HTML從JS中抽離:不要在innerHTML中拼接DOM結(jié)構(gòu),而是使用字符串模板,如handlerbars

全局變量

創(chuàng)建全局變量被認為是糟糕的實踐,尤其在團隊開發(fā)的大背景下更是問題多多。隨著代碼量的增長,全局變量會導(dǎo)致一些非常重要的可維護性難題,全局變量越多,引入錯誤的概率會變得越高
一般而言,有如下三種解決辦法
1、零全局變量
實現(xiàn)方法是使用一個立即調(diào)用函數(shù)IIFE并將所有腳本放置其中

HTML復(fù)制全屏

(function(){

var doc = win.document;

})(window);
這種模式的使用場景有限,只要代碼需要被其他的代碼所依賴,或者需要在運行中被不斷擴展或修改,就不能使用這種方式
2、單全局變量和命名空間
依賴盡可能少的全局變量,即只創(chuàng)建一個全局變量,使用單變量模式,如YUI或jQuery
單全局變量,即所創(chuàng)建的這個唯一全局對象名是獨一無二的,并將所有的功能代碼都掛載到這個全局對象上。因此,每個可能的全局變量,都成為唯一全局變量的屬性,從而不會創(chuàng)建多個全局變量
命名空間是簡單的通過全局對象的單一屬性表示的功能性分組。比如Y.DOM下的所有方法都是和DOM操作相關(guān)的,Y.Event下的所有方法都是和事件相關(guān)的。常見的約定是每個文件中都通過新的全局對象來聲明自己的命名空間
3、使用模塊
模塊是一種通用的功能片段,它并沒有創(chuàng)建新的全局變量或命名空間。相反,所有的這些代碼都存放于一個表示執(zhí)行一個任務(wù)或發(fā)布一個接口的單函數(shù)中。可以用一個名稱來表示這個模塊,同樣這個模塊可以依賴其他模塊

事件處理

將事件處理相關(guān)的代碼和事件環(huán)境耦合在一起,導(dǎo)致可維護性很糟糕
1、隔離應(yīng)用邏輯
將應(yīng)用邏輯從所有事件處理程序中抽離出來是一種最佳實踐,將應(yīng)用邏輯和事件處理的代碼拆分開來

HTML復(fù)制全屏

//不好的做法

function handleClick(event){

var popup = document.getElementById(‘popup’);

popup.style.left = event.clientX + ‘px’;

popup.style.top = event.clientY + ‘px’;

popup.className = ‘reveal’;

}
addListener(element,‘click’,handleClick);

//好的做法

var MyApplication = {

handleClick: function(event){

this.showPopup(event);

},
showPopup: function(event){

var popup = document.getElementById(‘popup’);

popup.style.left = event.clientX + ‘px’;

popup.style.top = event.clientY + ‘px’;

popup.className = ‘reveal’;

}

};

addListener(element,‘click’,function(event){

MyApplication.handleClick(event);

});
2、不要分發(fā)事件對象
應(yīng)用邏輯不應(yīng)當(dāng)依賴于event對象來正確完成功能,方法接口應(yīng)該表明哪些數(shù)據(jù)是必要的。代碼不清晰就會導(dǎo)致bug。最好的辦法是讓事件處理程序使用event對象來處理事件,然后拿到所有需要的數(shù)據(jù)傳給應(yīng)用邏輯

HTML復(fù)制全屏

//改進的做法

var MyApplication = {

handleClick: function(event){

this.showPopup(event.clientX,event.clientY);

},

showPopup: function(x,y){

var popup = document.getElementById(‘popup’);

popup.style.left = x + ‘px’;

popup.style.top = y + ‘px’;

popup.className = ‘reveal’;

}

};

addListener(element,‘click’,function(event){

MyApplication.handleClick(event);

});
當(dāng)處理事件時,最好讓事件程序成為接觸到event對象的唯一的函數(shù)。事件處理程序應(yīng)當(dāng)在進入應(yīng)用邏輯之前針對event對象執(zhí)行任何必要的操作,包括阻止事件冒泡,都應(yīng)當(dāng)直接包含在事件處理程序中

HTML復(fù)制全屏

//改進的做法

var MyApplication = {

handleClick: function(event){

event.preventDefault();

event.stopPropagation();

this.showPopup(event.clientX,event.clientY);

},

showPopup: function(x,y){

var popup = document.getElementById(‘popup’);

popup.style.left = x + ‘px’;

popup.style.top = y + ‘px’;

popup.className = ‘reveal’;

}

};

addListener(element,‘click’,function(event){

MyApplication.handleClick(event);

});
?
配置數(shù)據(jù)

代碼無非是定義一些指令的集合讓計算機來執(zhí)行。我們常常將數(shù)據(jù)傳入計算機,由指令對數(shù)據(jù)進行操作,并最終產(chǎn)生一個結(jié)果。當(dāng)不得不修改數(shù)據(jù)時,可能會帶來一些不必要的風(fēng)險。應(yīng)當(dāng)將關(guān)鍵數(shù)據(jù)從代碼中抽離出來
配置數(shù)據(jù)是指導(dǎo)在應(yīng)用中寫死的值,且將來可能會被修改,包括如下內(nèi)容

HTML復(fù)制全屏

1、URL

2、需要展現(xiàn)給用戶的字符串

3、重復(fù)的值

4、配置項

5、任何可能發(fā)生變更的值
下面是未處理配置數(shù)據(jù)的做法

HTML復(fù)制全屏

//不好的做法

function validate(value){

if(!value){

alert(‘Invalid value’);

location.href="/errors/invalid.php" rel=“external nofollow” ;

}

}

function toggleSelected(element){

if(hasClass(element,‘selected’)){

removeClass(element,‘selected’);

}else{

addClass(element,‘selected’);

}
}
下面代碼中將配置數(shù)據(jù)保存在了config對象中,config對象的每個屬性都保存了一個數(shù)據(jù)片段,每個屬性名都有前綴,用以表明數(shù)據(jù)的類型(MSG表示展現(xiàn)給用戶的信息,URL表示網(wǎng)絡(luò)地址,CSS表示這是一個className)。當(dāng)然,也可以將整個config對象放到單獨的文件中,這樣對配置數(shù)據(jù)的修改可以完全和使用這個數(shù)據(jù)的代碼隔離開來

HTML復(fù)制全屏

//好的做法

var config = {

MSG_INVALID_VALUE: ‘Invalid value’,

URL_INVALID:’/errors/invalid.php’,

CSS_SELECTED:‘selected’

}

function validate(value){

if(!value){

alert(config.MSG_INVALID_VALUE);
location.href=config.URL_INVALID;

}
}

function toggleSelected(element){

if(hasClass(element,config.CSS_SELECTED)){

removeClass(element,config.CSS_SELECTED);

}else{

addClass(element,config.CSS_SELECTED);

}
}
選擇器優(yōu)化

將選擇器選擇到的元素作為對象的靜態(tài)屬性集中到一個地方統(tǒng)一管理

HTML復(fù)制全屏

initializeElements: function() {

var eles = app.Eles;

for (var name in eles) {

if (eles.hasOwnProperty(name)) {

this[name] = $(eles[name]);

}

}

}
下面是一個例子

HTML復(fù)制全屏

//好的做法app.Eles = {

widgetDiv: “.left-widget div”,

inputResize: ‘.input-resize’,

hr: ‘.hr’,

txt: ‘.input-group-btn button’,

cus: ‘#paper-type-cus’,

hid: ‘#hidden’,

mainCon: ‘#mainCon’,

rulerX: ‘.ruler-x’,

rulerY: ‘.ruler-y’,

};
函數(shù)優(yōu)化

【提煉函數(shù)】
在javascript開發(fā)中,大部分時間都在與函數(shù)打交道,所以希望這些函數(shù)有著良好的命名,函數(shù)體內(nèi)包含的邏輯清晰明了。如果一個函數(shù)過長,不得不加上若干注釋才能讓這個函數(shù)顯得易讀一些,那這些函數(shù)就很有必要進行重構(gòu)
如果在函數(shù)中有一段代碼可以被獨立出來,那最好把這些代碼放進另外一個獨立的函數(shù)中。這是一種很常見的優(yōu)化工作,這樣做的好處主要有以下幾點
1、避免出現(xiàn)超大函數(shù),還有使用純函數(shù)最佳
2、獨立出來的函數(shù)有助于代碼復(fù)用
3、獨立出來的函數(shù)更容易被覆寫
4、獨立出來的函數(shù)如果擁有一個良好的命名,它本身就起到了注釋的作用
比如在一個負責(zé)取得用戶信息的函數(shù)里面,還需要打印跟用戶信息有關(guān)的log,那么打印log的語句就可以被封裝在一個獨立的函數(shù)里:

HTML復(fù)制全屏

var getUserInfo = function(){

ajax( ‘http:// xxx.com/userInfo’, function( data ){

console.log( 'userId: ' + data.userId );

console.log( 'userName: ' + data.userName );

console.log( 'nickName: ' + data.nickName );

});

};

//改成:

var getUserInfo = function(){

ajax( ‘http:// xxx.com/userInfo’, function( data ){

printDetails( data );
1
});

};

var printDetails = function( data ){

console.log( 'userId: ’ + data.userId );

console.log( 'userName: ’ + data.userName );

console.log( 'nickName: ’ + data.nickName );

};/歡迎加入前端全棧開發(fā)交流圈一起吹水聊天學(xué)習(xí)交流:619586920
【盡量減少參數(shù)數(shù)量】
如果調(diào)用一個函數(shù)時需要傳入多個參數(shù),那這個函數(shù)是讓人望而生畏的,必須搞清楚這些參數(shù)代表的含義,必須小心翼翼地把它們按照順序傳入該函數(shù)。在實際開發(fā)中,向函數(shù)傳遞參數(shù)不可避免,但應(yīng)該盡量減少函數(shù)接收的參數(shù)數(shù)量。下面舉個非常簡單的示例。有一個畫圖函數(shù)draw,它現(xiàn)在只能繪制正方形,接收了3個參數(shù),分別是圖形的width、heigth以及square:

HTML復(fù)制全屏

var draw = function(width,height,square){};
但實際上正方形的面積是可以通過width和height計算出來的,于是我們可以把參數(shù)square從draw函數(shù)中去掉:

HTML復(fù)制全屏

var draw = function( width, height ){

var square = width * height;

};
假設(shè)以后這個draw函數(shù)開始支持繪制圓形,需要把參數(shù)width和height換成半徑radius,但圖形的面積square始終不應(yīng)該由客戶傳入,而是應(yīng)該在draw函數(shù)內(nèi)部,由傳入的參數(shù)加上一定的規(guī)則計算得來。此時,可以使用策略模式,讓draw函數(shù)成為一個支持繪制多種圖形的函數(shù)
【傳遞對象參數(shù)代替過長的參數(shù)列表】
有時候一個函數(shù)有可能接收多個參數(shù),而參數(shù)的數(shù)量越多,函數(shù)就越難理解和使用。使用該函數(shù)的人首先得搞明白全部參數(shù)的含義,在使用的時候,還要小心翼翼,以免少傳了某個參數(shù)或者把兩個參數(shù)搞反了位置。如果想在第3個參數(shù)和第4個參數(shù)之中增加一個新的參數(shù),就會涉及許多代碼的修改,代碼如下:

HTML復(fù)制全屏

var setUserInfo = function( id, name, address, sex, mobile, qq ){

console.log( 'id= ’ + id );

console.log( 'name= ’ +name );

console.log( 'address= ’ + address );

console.log( 'sex= ’ + sex );

console.log( 'mobile= ’ + mobile );

console.log( 'qq= ’ + qq );

};
setUserInfo( 1314, ‘xiaohuochai’, ‘beijing’, ‘male’, ‘150’, 121631835 );

?
這時可以把參數(shù)都放入一個對象內(nèi),然后把該對象傳入setUserInfo函數(shù),setUserInfo函數(shù)需要的數(shù)據(jù)可以自行從該對象里獲取。現(xiàn)在不用再關(guān)心參數(shù)的數(shù)量和順序,只要保證參數(shù)對應(yīng)的key值不變就可以了:

HTML復(fù)制全屏

var setUserInfo = function( obj ){

console.log( 'id= ' + obj.id );

console.log( 'name= ' + obj.name );

console.log( 'address= ' + obj.address );

console.log( 'sex= ' + obj.sex );

console.log( 'mobile= ' + obj.mobile );

console.log( 'qq= ' + obj.qq );

};

setUserInfo({

id: 1314,

name: 'xiaohuochai',

address: 'beijing',

sex: 'male',

mobile: '150',

});
條件優(yōu)化

【合并條件片段】
如果一個函數(shù)體內(nèi)有一些條件分支語句,而這些條件分支語句內(nèi)部散布了一些重復(fù)的代碼,那么就有必要進行合并去重工作。假如有一個分頁函數(shù)paging,該函數(shù)接收一個參數(shù)currPage,currPage表示即將跳轉(zhuǎn)的頁碼。在跳轉(zhuǎn)之前,為防止currPage傳入過小或者過大的數(shù)字,要手動對它的值進行修正,詳見如下偽代碼:

HTML復(fù)制全屏

var paging = function( currPage ){

if ( currPage <= 0 ){

currPage = 0;

jump( currPage ); // 跳轉(zhuǎn)

}else if ( currPage >= totalPage ){

currPage = totalPage;

jump( currPage ); // 跳轉(zhuǎn)

}else{

jump( currPage ); // 跳轉(zhuǎn)

}
};
可以看到,負責(zé)跳轉(zhuǎn)的代碼jump(currPage)在每個條件分支內(nèi)都出現(xiàn)了,所以完全可以把這句代碼獨立出來:

HTML復(fù)制全屏

var paging = function( currPage ){

if ( currPage <= 0 ){

currPage = 0;
1
}else if ( currPage >= totalPage ){

currPage = totalPage;
1
}

jump( currPage ); // 把jump 函數(shù)獨立出來

};
【把條件分支語句提煉成函數(shù)】
在程序設(shè)計中,復(fù)雜的條件分支語句是導(dǎo)致程序難以閱讀和理解的重要原因,而且容易導(dǎo)致一個龐大的函數(shù)。假設(shè)現(xiàn)在有一個需求是編寫一個計算商品價格的getPrice函數(shù),商品的計算只有一個規(guī)則:如果當(dāng)前正處于夏季,那么全部商品將以8折出售。代碼如下:

HTML復(fù)制全屏

var getPrice = function( price ){

var date = new Date();

if ( date.getMonth() >= 6 && date.getMonth() <= 9 ){ // 夏天

return price * 0.8;
1
}

return price;

};
觀察這句代碼:

HTML復(fù)制全屏

date.getMonth()>=6&&date.getMonth()<=9
這句代碼要表達的意思很簡單,就是判斷當(dāng)前是否正處于夏天(7~10月)。盡管這句代碼很短小,但代碼表達的意圖和代碼自身還存在一些距離,閱讀代碼的人必須要多花一些精力才能明白它傳達的意圖。其實可以把這句代碼提煉成一個單獨的函數(shù),既能更準確地表達代碼的意思,函數(shù)名本身又能起到注釋的作用。代碼如下:

HTML復(fù)制全屏

var isSummer = function(){

var date = new Date();

return date.getMonth() >= 6 && date.getMonth() <= 9;

};
var getPrice = function( price ){

if ( isSummer() ){ // 夏天

return price * 0.8;
1
}

return price;

};
【提前讓函數(shù)退出代替嵌套條件分支】
許多程序員都有這樣一種觀念:“每個函數(shù)只能有一個入口和一個出口。”現(xiàn)代編程語言都會限制函數(shù)只有一個入口。但關(guān)于“函數(shù)只有一個出口”,往往會有一些不同的看法。下面這段偽代碼是遵守“函數(shù)只有一個出口的”的典型代碼:

HTML復(fù)制全屏

var del = function( obj ){

var ret;

if ( !obj.isReadOnly ){ // 不為只讀的才能被刪除

if ( obj.isFolder ){ // 如果是文件夾

ret = deleteFolder( obj );

}else if ( obj.isFile ){ // 如果是文件

ret = deleteFile( obj );

}

}

return ret;

};
嵌套的條件分支語句絕對是代碼維護者的噩夢,對于閱讀代碼的人來說,嵌套的if、else語句相比平鋪的if、else,在閱讀和理解上更加困難。嵌套的條件分支往往是由一些深信“每個函數(shù)只能有一個出口的”程序員寫出的。但實際上,如果對函數(shù)的剩余部分不感興趣,那就應(yīng)該立即退出。引導(dǎo)閱讀者去看一些沒有用的else片段,只會妨礙他們對程序的理解
于是可以挑選一些條件分支,在進入這些條件分支之后,就立即讓這個函數(shù)退出。要做到這一點,有一個常見的技巧,即在面對一個嵌套的if分支時,可以把外層if表達式進行反轉(zhuǎn)。重構(gòu)后的del函數(shù)如下:

HTML復(fù)制全屏

var del = function( obj ){

if ( obj.isReadOnly ){ // 反轉(zhuǎn)if 表達式

return;
1
}

if ( obj.isFolder ){

return deleteFolder( obj );
1
}

if ( obj.isFile ){

return deleteFile( obj );
1
}

};
循環(huán)優(yōu)化

【合理使用循環(huán)】
在函數(shù)體內(nèi),如果有些代碼實際上負責(zé)的是一些重復(fù)性的工作,那么合理利用循環(huán)不僅可以完成同樣的功能,還可以使代碼量更少。下面有一段創(chuàng)建XHR對象的代碼,為了簡化示例,只考慮版本9以下的IE瀏覽器,代碼如下:

HTML復(fù)制全屏

var createXHR = function(){
var xhr;
try{
xhr = new ActiveXObject( ‘MSXML2.XMLHttp.6.0’ );
}catch(e){
try{
xhr = new ActiveXObject( ‘MSXML2.XMLHttp.3.0’ );
}catch(e){
xhr = new ActiveXObject( ‘MSXML2.XMLHttp’ );
}
}
return xhr;
};
var xhr = createXHR();
下面靈活地運用循環(huán),可以得到跟上面代碼一樣的效果:

HTML復(fù)制全屏

1
//下面我們靈活地運用循環(huán),可以得到跟上面代碼一樣的效果:
2
var createXHR = function(){
3
var versions= [ ‘MSXML2.XMLHttp.6.0ddd’, ‘MSXML2.XMLHttp.3.0’, ‘MSXML2.XMLHttp’ ];
4
for ( var i = 0, version; version = versions[ i++ ]; ){
5
try{
6
return new ActiveXObject( version );
7
}catch(e){
8
}
9
}
10
};
11
var xhr = createXHR();
【用return退出多重循環(huán)】
假設(shè)在函數(shù)體內(nèi)有一個兩重循環(huán)語句,需要在內(nèi)層循環(huán)中判斷,當(dāng)達到某個臨界條件時退出外層的循環(huán)。大多數(shù)時候會引入一個控制標記變量:

HTML復(fù)制全屏

var func = function(){
var flag = false;
for ( var i = 0; i < 10; i++ ){
for ( var j = 0; j < 10; j++ ){
if ( i * j >30 ){
flag = true;
break;
}
}
if ( flag === true ){
break;
}
}
};
第二種做法是設(shè)置循環(huán)標記:

HTML復(fù)制全屏

var func = function(){

outerloop:

for ( var i = 0; i < 10; i++ ){
innerloop:
for ( var j = 0; j < 10; j++ ){
if ( i * j >30 ){
break outerloop;
}
}
}
};
這兩種做法無疑都讓人頭暈?zāi)垦?#xff0c;更簡單的做法是在需要中止循環(huán)的時候直接退出整個方法:

HTML復(fù)制全屏

var func = function(){

for ( var i = 0; i < 10; i++ ){

for ( var j = 0; j < 10; j++ ){

if ( i * j >30 ){

return;

}

}

}

};
當(dāng)然用return直接退出方法會帶來一個問題,如果在循環(huán)之后還有一些將被執(zhí)行的代碼呢?如果提前退出了整個方法,這些代碼就得不到被執(zhí)行的機會:
歡迎加入web前端學(xué)習(xí)群,群聊號碼:512676244,進群可免費領(lǐng)取2019最新學(xué)習(xí)資料一套,福利難得哦!
HTML復(fù)制全屏

var func = function(){

for ( var i = 0; i < 10; i++ ){

for ( var j = 0; j < 10; j++ ){

if ( i * j >30 ){

return;

}
}

}
console.log( i ); // 這句代碼沒有機會被執(zhí)行

};

var print = function( i ){

console.log( i );

};

var func = function(){

for ( var i = 0; i < 10; i++ ){

for ( var j = 0; j < 10; j++ ){

if ( i * j >30 ){

return print( i );

}

}

}

};func();

總結(jié)

以上是生活随笔為你收集整理的Javascript代码优化的8个知识点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。