鑒于想讓自己有一個提升,進不了一個更加廣闊的天地席噩,總得找一個屬于自己的居所好好生存班缰,所以平時會有意無意的去積累一些使用 jQuerry 的常用知識,特別是對于性能要求這一塊班挖,總是會想是不是有更好的方式來實現(xiàn)鲁捏。下面是我總結(jié)的一些小技巧,僅供參考。
前言
一直在學(xué)習(xí) javascript给梅,也有看過《犀利開發(fā) Jquery 內(nèi)核詳解與實踐》假丧,對這本書的評價只有兩個字犀利,可能是對 javascript 理解的還不夠透徹異或是自己太笨动羽,更多的是自己不擅于思考懶得思考以至于里面說的一些精髓都沒有太深入的理解包帚。
鑒于想讓自己有一個提升,進不了一個更加廣闊的天地运吓,總得找一個屬于自己的居所好好生存渴邦,所以平時會有意無意的去積累一些使用 jQuerry 的常用知識,特別是對于性能要求這一塊拘哨,總是會想是不是有更好的方式來實現(xiàn)谋梭。
下面是我總結(jié)的一些小技巧,僅供參考倦青。(我先會說一個總標題瓮床,然后用一小段話來說明這個意思 再最后用一個 demo 來簡單言明)
避免全局查找
在一個函數(shù)中會用到全局對象存儲為局部變量來減少全局查找,因為訪問局部變量的速度要比訪問全局變量的速度更快些
function search() {
//當(dāng)我要使用當(dāng)前頁面地址和主機域名
alert(window.location.href + window.location.host);
}
//最好的方式是如下這樣 先用一個簡單變量保存起來
function search() {
var location = window.location;
alert(location.href + location.host);
}
定時器
如果針對的是不斷運行的代碼产镐,不應(yīng)該使用 setTimeout隘庄,而應(yīng)該是用 setInterval,因為 setTimeout 每一次都會初始化一個定時器癣亚,而 setInterval 只會在開始的時候初始化一個定時器
var timeoutTimes = 0;
function timeout() {
timeoutTimes++;
if (timeoutTimes < 10) {
setTimeout(timeout, 10);
}
}
timeout();
//可以替換為:
var intervalTimes = 0;
function interval() {
intervalTimes++;
if (intervalTimes >= 10) {
clearInterval(interv);
}
}
var interv = setInterval(interval, 10);
字符串連接
如果要連接多個字符串丑掺,應(yīng)該少使用 +=,如
s+=a;
s+=b;
s+=c;
應(yīng)該寫成 s+=a + b + c述雾;
而如果是收集字符串街州,比如多次對同一個字符串進行 += 操作的話,最好使用一個緩存玻孟,使用 JavaScript 數(shù)組來收集菇肃,最后使用 join 方法連接起來
var buf = [];
for (var i = 0; i < 100; i++) {
buf.push(i.toString());
}
var all = buf.join("");
避免 with 語句
和函數(shù)類似 ,with 語句會創(chuàng)建自己的作用域取募,因此會增加其中執(zhí)行的代碼的作用域鏈的長度,由于額外的作用域鏈的查找蟆技,在 with 語句中執(zhí)行的代碼肯定會比外面執(zhí)行的代碼要慢玩敏,在能不使用 with 語句的時候盡量不要使用 with 語句。
with (a.b.c.d) {
property1 = 1;
property2 = 2;
}
//可以替換為:
var obj = a.b.c.d;
obj.property1 = 1;
obj.property2 = 2;
數(shù)字轉(zhuǎn)換成字符串
般最好用 "" + 1 來將數(shù)字轉(zhuǎn)換成字符串质礼,雖然看起來比較丑一點旺聚,但事實上這個效率是最高的,性能上來說:
("" +) > String() > .toString() > new String()
浮點數(shù)轉(zhuǎn)換成整型
很多人喜歡使用 parseInt()眶蕉,其實 parseInt() 是用于將字符串轉(zhuǎn)換成數(shù)字砰粹,而不是浮點數(shù)和整型之間的轉(zhuǎn)換,我們應(yīng)該使用 Math.floor() 或者 Math.round()
各種類型轉(zhuǎn)換
var myVar = "3.14159",
str = "" + myVar, // to string
i_int = ~ ~myVar, // to integer
f_float = 1 * myVar, // to float
b_bool = !!myVar, /* to boolean - any string with length
and any number except 0 are true */
array = [myVar]; // to array
如果定義了 toString() 方法來進行類型轉(zhuǎn)換的話造挽,推薦顯式調(diào)用 toString()碱璃,因為內(nèi)部的操作在嘗試所有可能性之后弄痹,會嘗試對象的 toString() 方法嘗試能否轉(zhuǎn)化為 String,所以直接調(diào)用這個方法效率會更高
多個類型聲明
在 JavaScript 中所有變量都可以使用單個 var 語句來聲明嵌器,這樣就是組合在一起的語句肛真,以減少整個腳本的執(zhí)行時間,就如上面代碼一樣爽航,上面代碼格式也挺規(guī)范蚓让,讓人一看就明了。
插入迭代器
如
var name=values[i]; i++;
前面兩條語句可以寫成
var name=values[i++]
使用直接量
var aTest = new Array(); //替換為
var aTest = [];
var aTest = new Object; //替換為
var aTest = {};
var reg = new RegExp(); //替換為
var reg = /../;
//如果要創(chuàng)建具有一些特性的一般對象讥珍,也可以使用字面量历极,如下:
var oFruit = new O;
oFruit.color = "red";
oFruit.name = "apple";
//前面的代碼可用對象字面量來改寫成這樣:
var oFruit = { color: "red", name: "apple" };
一旦需要更新 DOM, 請考慮使用文檔碎片來構(gòu)建 DOM 結(jié)構(gòu),然后再將其添加到現(xiàn)存的文檔中衷佃。
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
document.body.appendChild(el);
}
//可以替換為:
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);
使用一次 innerHTML 賦值代替構(gòu)建 dom 元素
對于大的 DOM 更改趟卸,使用 innerHTML 要比使用標準的 DOM 方法創(chuàng)建同樣的 DOM 結(jié)構(gòu)快得多。
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);
//可以替換為:
var html = [];
for (var i = 0; i < 1000; i++) {
html.push('
' + i + '
');
}
document.body.innerHTML = html.join('');
通過模板元素 clone纲酗,替代 createElement
很多人喜歡在 JavaScript 中使用 document.write 來給頁面生成內(nèi)容衰腌。事實上這樣的效率較低,如果需要直接插入 HTML觅赊,可以找一個容器元素右蕊,比如指定一個 div 或者 span,并設(shè)置他們的 innerHTML 來將自己的 HTML 代碼插入到頁面中吮螺。通常我們可能會使用字符串直接寫 HTML 來創(chuàng)建節(jié)點饶囚,其實這樣做,1 無法保證代碼的有效性 2 字符串操作效率低鸠补,所以應(yīng)該是用 document.createElement() 方法萝风,而如果文檔中存在現(xiàn)成的樣板節(jié)點,應(yīng)該是用 cloneNode() 方法紫岩,因為使用 createElement() 方法之后规惰,你需要設(shè)置多次元素的屬性,使用 cloneNode() 則可以減少屬性的設(shè)置次數(shù)——同樣如果需要創(chuàng)建很多元素泉蝌,應(yīng)該先準備一個樣板節(jié)點
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);
//替換為:
var frag = document.createDocumentFragment();
var pEl = document.getElementsByTagName('p')[0];
for (var i = 0; i < 1000; i++) {
var el = pEl.cloneNode(false);
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
使用 firstChild 和 nextSibling 代替 childNodes 遍歷 dom 元素
var nodes = element.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i];
//……
}
//可以替換為:
var node = element.firstChild;
while (node) {
//……
node = node.nextSibling;
刪除 DOM 節(jié)點
刪除 dom 節(jié)點之前, 一定要刪除注冊在該節(jié)點上的事件, 不管是用 observe 方式還是用 attachEvent 方式注冊的事件, 否則將會產(chǎn)生無法回收的內(nèi)存歇万。另外,在 removeChild 和 innerHTML=’’二者之間, 盡量選擇后者. 因為在 sIEve(內(nèi)存泄露監(jiān)測工具) 中監(jiān)測的結(jié)果是用 removeChild 無法有效地釋放 dom 節(jié)點
使用事件代理
任何可以冒泡的事件都不僅僅可以在事件目標上進行處理勋陪,目標的任何祖先節(jié)點上也能處理贪磺,使用這個知識就可以將事件處理程序附加到更高的地方負責(zé)多個目標的事件處理,同樣诅愚,對于內(nèi)容動態(tài)增加并且子節(jié)點都需要相同的事件處理函數(shù)的情況寒锚,可以把事件注冊提到父節(jié)點上,這樣就不需要為每個子節(jié)點注冊事件監(jiān)聽了。另外刹前,現(xiàn)有的 js 庫都采用 observe 方式來創(chuàng)建事件監(jiān)聽, 其實現(xiàn)上隔離了 dom 對象和事件處理函數(shù)之間的循環(huán)引用, 所以應(yīng)該盡量采用這種方式來創(chuàng)建事件監(jiān)聽
重復(fù)使用的調(diào)用結(jié)果泳赋,事先保存到局部變量
//避免多次取值的調(diào)用開銷
var h1 = element1.clientHeight + num1;
var h4 = element1.clientHeight + num2;
//可以替換為:
var eleHeight = element1.clientHeight;
var h1 = eleHeight + num1;
var h4 = eleHeight + num2;
注意 NodeList
最小化訪問 NodeList 的次數(shù)可以極大的改進腳本的性能
var images = document.getElementsByTagName('img');
for (var i = 0, len = images.length; i < len; i++) {
}
編寫 JavaScript 的時候一定要知道何時返回 NodeList 對象,這樣可以最小化對它們的訪問
進行了對 getElementsByTagName() 的調(diào)用
獲取了元素的 childNodes 屬性
獲取了元素的 attributes 屬性
訪問了特殊的集合腮郊,如 document.forms摹蘑、document.images 等等
要了解了當(dāng)使用 NodeList 對象時,合理使用會極大的提升代碼執(zhí)行速度
優(yōu)化循環(huán)
可以使用下面幾種方式來優(yōu)化循環(huán)
減值迭代
大多數(shù)循環(huán)使用一個從 0 開始轧飞、增加到某個特定值的迭代器衅鹿,在很多情況下,從最大值開始过咬,在循環(huán)中不斷減值的迭代器更加高效
簡化終止條件
由于每次循環(huán)過程都會計算終止條件大渤,所以必須保證它盡可能快,也就是說避免屬性查找或者其它的操作掸绞,最好是將循環(huán)控制量保存到局部變量中泵三,也就是說對數(shù)組或列表對象的遍歷時,提前將 length 保存到局部變量中衔掸,避免在循環(huán)的每一步重復(fù)取值烫幕。
var list = document.getElementsByTagName('p');
for (var i = 0; i < list.length; i++) {
//……
}
//替換為:
var list = document.getElementsByTagName('p');
for (var i = 0, l = list.length; i < l; i++) {
//……
}
簡化循環(huán)體
循環(huán)體是執(zhí)行最多的,所以要確保其被最大限度的優(yōu)化
使用后測試循環(huán)
在 JavaScript 中敞映,我們可以使用 for(;;),while(),for(in) 三種循環(huán)较曼,事實上,這三種循環(huán)中 for(in) 的效率極差振愿,因為他需要查詢散列鍵捷犹,只要可以,就應(yīng)該盡量少用冕末。for(;;) 和 while 循環(huán)萍歉,while 循環(huán)的效率要優(yōu)于 for(;;),可能是因為 for(;;) 結(jié)構(gòu)的問題档桃,需要經(jīng)常跳轉(zhuǎn)回去枪孩。
var arr = [1, 2, 3, 4, 5, 6, 7];
var sum = 0;
for (var i = 0, l = arr.length; i < l; i++) {
sum += arr[i];
}
//可以考慮替換為:
var arr = [1, 2, 3, 4, 5, 6, 7];
var sum = 0, l = arr.length;
while (l--) {
sum += arr[l];
}
最常用的 for 循環(huán)和 while 循環(huán)都是前測試循環(huán),而如 do-while 這種后測試循環(huán)藻肄,可以避免最初終止條件的計算销凑,因此運行更快。
展開循環(huán)
當(dāng)循環(huán)次數(shù)是確定的仅炊,消除循環(huán)并使用多次函數(shù)調(diào)用往往會更快。
避免雙重解釋
如果要提高代碼性能澎蛛,盡可能避免出現(xiàn)需要按照 JavaScript 解釋的字符串抚垄,也就是
盡量少使用 eval 函數(shù)
使用 eval 相當(dāng)于在運行時再次調(diào)用解釋引擎對內(nèi)容進行運行,需要消耗大量時間,而且使用 Eval 帶來的安全性問題也是不容忽視的呆馁。
不要使用 Function 構(gòu)造器
不要給 setTimeout 或者 setInterval 傳遞字符串參數(shù)
var num = 0;
setTimeout('num++', 10);
//可以替換為:
var num = 0;
function addNum() {
num++;
}
setTimeout(addNum, 10);
縮短否定檢測
if (oTest != '#ff0000') {
//do something
}
if (oTest != null) {
//do something
}
if (oTest != false) {
//do something
}
//雖然這些都正確桐经,但用邏輯非操作符來操作也有同樣的效果:
if (!oTest) {
//do something
}
條件分支
將條件分支,按可能性順序從高到低排列:可以減少解釋器對條件的探測次數(shù)
在同一條件子的多(>2)條件分支時浙滤,使用 switch 優(yōu)于 if:switch 分支選擇的效率高于 if阴挣,在 IE 下尤為明顯。4 分支的測試纺腊,IE 下 switch 的執(zhí)行時間約為 if 的一半畔咧。
使用三目運算符替代條件分支
if (a > b) {
num = a;
} else {
num = b;
}
//可以替換為:
num = a > b ? a : b;
使用常量
重復(fù)值: 任何在多處用到的值都應(yīng)該抽取為一個常量
用戶界面字符串: 任何用于顯示給用戶的字符串,都應(yīng)該抽取出來以方便國際化
URLs: 在 Web 應(yīng)用中揖膜,資源位置很容易變更誓沸,所以推薦用一個公共地方存放所有的 URL
任意可能會更改的值: 每當(dāng)你用到字面量值的時候,你都要問一下自己這個值在未來是不是會變化壹粟,如果答案是 “是”拜隧,那么這個值就應(yīng)該被提取出來作為一個常量。
避免與 null 進行比較
由于 JavaScript 是弱類型的趁仙,所以它不會做任何的自動類型檢查洪添,所以如果看到與 null 進行比較的代碼,嘗試使用以下技術(shù)替換
如果值應(yīng)為一個引用類型雀费,使用 instanceof 操作符檢查其構(gòu)造函數(shù)
如果值應(yīng)為一個基本類型干奢,作用 typeof 檢查其類型
如果是希望對象包含某個特定的方法名,則使用 typeof 操作符確保指定名字的方法存在于對象上
避免全局量
全局變量應(yīng)該全部字母大寫坐儿,各單詞之間用_下劃線來連接律胀。盡可能避免全局變量和函數(shù), 盡量減少全局變量的使用,因為在一個頁面中包含的所有 JavaScript 都在同一個域中運行貌矿。所以如果你的代碼中聲明了全局變量或者全局函數(shù)的話炭菌,后面的代碼中載入的腳本文件中的同名變量和函數(shù)會覆蓋掉(overwrite)你的。
//糟糕的全局變量和全局函數(shù)
var current = null;
function init(){
//...
}
function change() {
//...
}
function verify() {
//...
}
//解決辦法有很多逛漫,Christian Heilmann建議的方法是:
//如果變量和函數(shù)不需要在“外面”引用黑低,那么就可以使用一個沒有名字的方法將他們?nèi)及饋怼?/p>
(function(){
var current = null;
function init() {
//...
}
function change() {
//...
}
function verify() {
//...
}
})();
//如果變量和函數(shù)需要在“外面”引用,需要把你的變量和函數(shù)放在一個“命名空間”中
//我們這里用一個function做命名空間而不是一個var酌毡,因為在前者中聲明function更簡單克握,而且能保護隱私數(shù)據(jù)
myNameSpace = function() {
var current = null;
function init() {
//...
}
function change() {
//...
}
function verify() {
//...
}
//所有需要在命名空間外調(diào)用的函數(shù)和屬性都要寫在return里面
return {
init: init,
//甚至你可以為函數(shù)和屬性命名一個別名
set: change
};
};
尊重對象的所有權(quán)
因為 JavaScript 可以在任何時候修改任意對象,這樣就可以以不可預(yù)計的方式覆寫默認的行為枷踏,所以如果你不負責(zé)維護某個對象菩暗,它的對象或者它的方法,那么你就不要對它進行修改旭蠕,具體一點就是說:
不要為實例或原型添加屬性
不要為實例或者原型添加方法
不要重定義已經(jīng)存在的方法
不要重復(fù)定義其它團隊成員已經(jīng)實現(xiàn)的方法停团,永遠不要修改不是由你所有的對象旷坦,你可以通過以下方式為對象創(chuàng)建新的功能:
創(chuàng)建包含所需功能的新對象,并用它與相關(guān)對象進行交互
創(chuàng)建自定義類型佑稠,繼承需要進行修改的類型秒梅,然后可以為自定義類型添加額外功能
循環(huán)引用
如果循環(huán)引用中包含 DOM 對象或者 ActiveX 對象,那么就會發(fā)生內(nèi)存泄露舌胶。內(nèi)存泄露的后果是在瀏覽器關(guān)閉前捆蜀,即使是刷新頁面,這部分內(nèi)存不會被瀏覽器釋放幔嫂。
簡單的循環(huán)引用:
var el = document.getElementById('MyElement');
var func = function () {
//…
}
el.func = func;
func.element = el;
但是通常不會出現(xiàn)這種情況辆它。通常循環(huán)引用發(fā)生在為 dom 元素添加閉包作為 expendo 的時候。
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {
//……
}
}
init();
init 在執(zhí)行的時候婉烟,當(dāng)前上下文我們叫做 context娩井。這個時候,context 引用了 el似袁,el 引用了 function洞辣,function 引用了 context。這時候形成了一個循環(huán)引用昙衅。
下面 2 種方法可以解決循環(huán)引用:
1.置空 dom 對象
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {
//……
}
}
init();
//可以替換為:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {
//……
}
el = null;
}
init();
將 el 置空扬霜,context 中不包含對 dom 對象的引用,從而打斷循環(huán)應(yīng)用而涉。
如果我們需要將 dom 對象返回著瓶,可以用如下方法:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {
//……
}
return el;
}
init();
//可以替換為:
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {
//……
}
try {
return el;
} finally {
el = null;
}
}
init();
2. 構(gòu)造新的 context
function init() {
var el = document.getElementById('MyElement');
el.onclick = function () {
//……
}
}
init();
//可以替換為:
function elClickHandler() {
//……
}
function init() {
var el = document.getElementById('MyElement');
el.onclick = elClickHandler;
}
init();
把 function 抽到新的 context 中,這樣啼县,function 的 context 就不包含對 el 的引用材原,從而打斷循環(huán)引用。
通過 javascript 創(chuàng)建的 dom 對象季眷,必須 append 到頁面中
IE 下余蟹,腳本創(chuàng)建的 dom 對象,如果沒有 append 到頁面中子刮,刷新頁面威酒,這部分內(nèi)存是不會回收的!
function create() {
var gc = document.getElementById('GC');
for (var i = 0; i < 5000; i++) {
var el = document.createElement('div');
el.innerHTML = "test";
//下面這句可以注釋掉挺峡,看看瀏覽器在任務(wù)管理器中葵孤,點擊按鈕然后刷新后的內(nèi)存變化
gc.appendChild(el);
}
}
釋放 dom 元素占用的內(nèi)存
將 dom 元素的 innerHTML 設(shè)置為空字符串,可以釋放其子元素占用的內(nèi)存橱赠。
在 rich 應(yīng)用中尤仍,用戶也許會在一個頁面上停留很長時間,可以使用該方法釋放積累得越來越多的 dom 元素使用的內(nèi)存狭姨。
釋放 javascript 對象
在 rich 應(yīng)用中吓著,隨著實例化對象數(shù)量的增加鲤嫡,內(nèi)存消耗會越來越大。所以應(yīng)當(dāng)及時釋放對對象的引用绑莺,讓 GC 能夠回收這些內(nèi)存控件。
對象: obj = null
對象屬性: delete obj.myproperty
數(shù)組 item:使用數(shù)組的 splice 方法釋放數(shù)組中不用的 item
避免 string 的隱式裝箱
對 string 的方法調(diào)用惕耕,比如'xxx'.length纺裁,瀏覽器會進行一個隱式的裝箱操作,將字符串先轉(zhuǎn)換成一個 String 對象司澎。推薦對聲明有可能使用 String 實例方法的字符串時欺缘,采用如下寫法:
var myString = new String('Hello World');
松散耦合
1、解耦 HTML/JavaScript
JavaScript 和 HTML 的緊密耦合:直接寫在 HTML 中的 JavaScript挤安、使用包含內(nèi)聯(lián)代碼的 <script> 元素谚殊、使用 HTML 屬性來分配事件處理程序等
HTML 和 JavaScript 的緊密耦合:JavaScript 中包含 HTML,然后使用 innerHTML 來插入一段 html 文本到頁面
其實應(yīng)該是保持層次的分離蛤铜,這樣可以很容易的確定錯誤的來源嫩絮,所以我們應(yīng)確保 HTML 呈現(xiàn)應(yīng)該盡可能與 JavaScript 保持分離
2、解耦 CSS/JavaScript
顯示問題的唯一來源應(yīng)該是 CSS围肥,行為問題的唯一來源應(yīng)該是 JavaScript剿干,層次之間保持松散耦合才可以讓你的應(yīng)用程序更加易于維護,所以像以下的代碼 element.style.color="red" 盡量改為 element.className="edit"穆刻,而且不要在 css 中通過表達式嵌入 JavaScript
3置尔、解耦應(yīng)用程序 / 事件處理程序
將應(yīng)用邏輯和事件處理程序相分離:一個事件處理程序應(yīng)該從事件對象中提取,并將這些信息傳送給處理應(yīng)用邏輯的某個方法中氢伟。這樣做的好處首先可以讓你更容易更改觸發(fā)特定過程的事件榜轿,其次可以在不附加事件的情況下測試代碼,使其更易創(chuàng)建單元測試
性能方面的注意事項
1朵锣、盡量使用原生方法
2谬盐、switch 語句相對 if 較快
通過將 case 語句按照最可能到最不可能的順序進行組織
3、位運算較快
當(dāng)進行數(shù)字運算時猪勇,位運算操作要比任何布爾運算或者算數(shù)運算快
4设褐、巧用 ||和 && 布爾運算符
function eventHandler(e) {
if (!e) e = window.event;
}
//可以替換為:
function eventHandler(e) {
e = e || window.event;
}
if (myobj) {
doSomething(myobj);
}
//可以替換為:
myobj && doSomething(myobj);
避免錯誤應(yīng)注意的地方
1、每條語句末尾須加分號
在 if 語句中泣刹,即使條件表達式只有一條語句也要用 {} 把它括起來助析,以免后續(xù)如果添加了語句之后造成邏輯錯誤
2、使用 + 號時需謹慎
JavaScript 和其他編程語言不同的是椅您,在 JavaScript 中外冀,'+'除了表示數(shù)字值相加,字符串相連接以外掀泳,還可以作一元運算符用雪隧,把字符串轉(zhuǎn)換為數(shù)字西轩。因而如果使用不當(dāng),則可能與自增符'++'混淆而引起計算錯誤
var valueA = 20;
var valueB = "10";
alert(valueA + valueB); //ouput: 2010
alert(valueA + (+valueB)); //output: 30
alert(valueA + +valueB); //output:30
alert(valueA ++ valueB); //Compile error
3脑沿、使用 return 語句需要注意
一條有返回值的 return 語句不要用 () 括號來括住返回值藕畔,如果返回表達式,則表達式應(yīng)與 return 關(guān)鍵字在同一行庄拇,以避免壓縮時注服,壓縮工具自動加分號而造成返回與開發(fā)人員不一致的結(jié)果
function F1() {
var valueA = 1;
var valueB = 2;
return valueA + valueB;
}
function F2() {
var valueA = 1;
var valueB = 2;
return
valueA + valueB;
}
alert(F1()); //output: 3
alert(F2()); //ouput: undefined
== 和 === 的區(qū)別
避免在 if 和 while 語句的條件部分進行賦值,如 if (a = b)措近,應(yīng)該寫成 if (a == b)溶弟,但是在比較是否相等的情況下,最好使用全等運行符瞭郑,也就是使用 === 和!== 操作符會相對于 == 和!= 會好點辜御。== 和!= 操作符會進行類型強制轉(zhuǎn)換
var valueA = "1";
var valueB = 1;
if (valueA == valueB) {
alert("Equal");
}
else {
alert("Not equal");
}
//output: "Equal"
if (valueA === valueB) {
alert("Equal");
}
else {
alert("Not equal");
}
//output: "Not equal"
不要使用生偏語法
不要使用生偏語法,寫讓人迷惑的代碼屈张,雖然計算機能夠正確識別并運行擒权,但是晦澀難懂的代碼不方便以后維護
函數(shù)返回統(tǒng)一類型
雖然 JavaScript 是弱類型的,對于函數(shù)來說袜茧,前面返回整數(shù)型數(shù)據(jù)菜拓,后面返回布爾值在編譯和運行都可以正常通過,但為了規(guī)范和以后維護時容易理解笛厦,應(yīng)保證函數(shù)應(yīng)返回統(tǒng)一的數(shù)據(jù)類型
總是檢查數(shù)據(jù)類型
要檢查你的方法輸入的所有數(shù)據(jù)纳鼎,一方面是為了安全性,另一方面也是為了可用性裳凸。用戶隨時隨地都會輸入錯誤的數(shù)據(jù)贱鄙。這不是因為他們蠢,而是因為他們很忙姨谷,并且思考的方式跟你不同逗宁。用 typeof 方法來檢測你的 function 接受的輸入是否合法
何時用單引號,何時用雙引號
雖然在 JavaScript 當(dāng)中梦湘,雙引號和單引號都可以表示字符串, 為了避免混亂瞎颗,我們建議在 HTML 中使用雙引號,在 JavaScript 中使用單引號捌议,但為了兼容各個瀏覽器哼拔,也為了解析時不會出錯,定義 JSON 對象時瓣颅,最好使用雙引號
部署
用 JSLint 運行 JavaScript 驗證器來確保沒有語法錯誤或者是代碼沒有潛在的問
部署之前推薦使用壓縮工具將 JS 文件壓縮
文件編碼統(tǒng)一用 UTF-8
JavaScript 程序應(yīng)該盡量放在 .js 的文件中倦逐,需要調(diào)用的時候在 HTML 中以 <script src="filename.js"> 的形式包含進來。JavaScript 代碼若不是該 HTML 文件所專用的宫补,則應(yīng)盡量避免在 HTML 文件中直接編寫 JavaScript 代碼檬姥。因為這樣會大大增加 HTML 文件的大小曾我,無益于代碼的壓縮和緩存的使用。另外健民, <script src="filename.js"> 標簽應(yīng)盡量放在文件的后面, 最好是放在 </body > 標簽前抒巢。這樣會降低因加載 JavaScript 代碼而影響頁面中其它組件的加載時間。
永遠不要忽略代碼優(yōu)化工作秉犹,重構(gòu)是一項從項目開始到結(jié)束需要持續(xù)的工作虐秦,只有不斷的優(yōu)化代碼才能讓代碼的執(zhí)行效率越來越好。
如果你是一名程序員凤优,如果你剛好又是Java程序員,恰巧剛好你的技術(shù)又遇到了瓶頸但是你又拒絕平庸蜈彼,期待蛻變筑辨,想進入一線互聯(lián)網(wǎng)公司或者給自己漲薪
我這里剛好有一套自己保存的Java進階學(xué)習(xí)資料。包含了Spring框架幸逆、Mybatis框架SpringBoot框架棍辕、SpringMVC框架、SpringCloud微服務(wù)还绘、Dubbo框架楚昭、Redis緩存、RabbitMq消息拍顷、JVM調(diào)優(yōu)抚太、Tomcat容器、MySQL數(shù)據(jù)庫
之前的兩千人群滿了 這個是新群Java高級進階群:963,944.895昔案,免費發(fā)送的喲