国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

Javascript實用黑科技45條

2018-06-09 18:13 更新
大綱
  1. 1. 使用var關鍵字進行變量賦值
  2. 2. 使用===來代替==進行判等
  3. 3. undefined,null,0,false,NaN,''(空字符串)都為邏輯假值
  4. 4. 使用分號;來結束一行代碼
  5. 5. 使用對象構造器
  6. 6. 使用typeof、instanceof、constructor時要謹慎小心
  7. 7. 學會使用自調用函數(shù)
  8. 8. 隨機從數(shù)組中取出一個元素
  9. 9. 從一個指定的范圍中取出一個隨機數(shù)
  10. 10. 生成一個從0開始到指定數(shù)字的序列
  11. 11. 生成一個隨機的字母數(shù)字序列
  12. 12. 打亂一個數(shù)字數(shù)組的順序
  13. 13. 字符串去空格
  14. 14. 將一個數(shù)組追加到另一個數(shù)組中
  15. 15. 將argruments轉換成數(shù)組
  16. 16. 檢驗一個參數(shù)是否為數(shù)字
  17. 17. 檢驗一個參數(shù)是否為數(shù)組
  18. 18. 取出一個數(shù)組中的最大值和最小值
  19. 19. 清空一個數(shù)組
  20. 20. 不用使用delete關鍵字來移除一個數(shù)組元素
  21. 21. 可以通過操作數(shù)組長度length來截斷一個數(shù)組
  22. 22. 在條件中使用&&及||進行短語判斷
  23. 23. 使用map()對數(shù)組進行遍歷操作
  24. 24. 保留指定位數(shù)的小數(shù)點
  25. 25. 浮點數(shù)計算問題
  26. 26. 使用for...in來遍歷對象的屬性
  27. 27. 逗號運算符
  28. 28. 緩存臨時變量用于避免再次計算或者查詢
  29. 29. 提前檢查傳入isFinite()的參數(shù)
  30. 30. 避免對數(shù)組進行負值索引
  31. 31. 使用JSON來進行序列化和反序列化
  32. 32. 避免使用eval()和函數(shù)構造器
  33. 33. 避免使用with()
  34. 34. 避免使用for...in遍歷數(shù)組
  35. 35. 給setTimeout()及setInterval()傳遞函數(shù)而不是字符串更好
  36. 36. 使用switch/case來代替一坨if/else
  37. 37. 在switch/case中使用數(shù)字范圍進行分界
  38. 38. 為創(chuàng)建的對象指定原型
  39. 39. html轉義函數(shù)
  40. 40. 不要在循環(huán)中使用try...catch...finally
  41. 41. 使用XMLHttpRequests時注意設置超時參數(shù)
  42. 42. 處理websocket超時
  43. 43. 記?。涸僮骺隙ū群瘮?shù)調用要效率高
  44. 44. 編碼時注意保持代碼的優(yōu)雅格式,上生產環(huán)境前做一些壓縮工作。
  45. 45. Javascript是一門很吊的語言,這里還有很多資源

本文是一篇翻譯文章。原文:45 Useful JavaScript Tips, Tricks and Best Practices

譯文開始。

眾所周知,Javascript是全球最流行的語言之一,它涉足Web開發(fā),移動端開發(fā)(PhoneGap、Appcelerator),服務端開發(fā)(Nodejs、Wakanda),還有多種第三方實現(xiàn)(CoffeeScript這種)。此外Javascript還是許多開發(fā)者進入編程世界所接觸的第一門語言。它既可以在瀏覽器中簡單的彈出一個alert窗口,也能達到控制機器人這種復雜的程度(比如nodebot、nodruino)?,F(xiàn)在那些能夠熟練編寫結構清晰、性能卓越的Javascript開發(fā)者們,已經成為招聘市場上炙手可熱的應聘者了。

在這篇文章中,我將向你展示一系列Javascript相關的小技巧和一些最佳實踐。除了少數(shù)幾個示例,大部分示例都可以在瀏覽器環(huán)境或者服務端環(huán)境適用。

注意,文章中所有的代碼片段都已經在Google Chrome V30(V8 3.20.17.15)測試通過。

使用var關鍵字進行變量賦值

在Javascript中,如果一個變量沒有經過聲明就直接進行賦值操作,那么這個變量就會自動轉變成全局變量。我們要盡量避免這種情況(全局變量)。

使用===來代替==進行判等

==!=操作符會在某些情況下自動進行類型轉化。但是===!==不會做自動轉化,它們在做比較時,會同時比較數(shù)據(jù)類型和值,這也使得===!==要比==!=的速度要快。

[10] === 10    // is false
[10]  == 10    // is true
'10' == 10     // is true
'10' === 10    // is false
[] == 0        // is true
[] ===  0      // is false
'' == false    // is true but true == "a" is false
'' ===   false // is false

undefined,null,0,falseNaN,''(空字符串)都為邏輯假值

使用分號;來結束一行代碼

使用分號來結束代碼行是一個被Javascript社區(qū)推薦的最佳實踐。如果你忘了也沒有關系,因為現(xiàn)在的Javascript引擎將會自動給你加上分號。至于我們?yōu)槭裁磻撌褂梅痔?,可以參閱這篇文章http://davidwalsh.name/javascript-semicolons

使用對象構造器

function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");

使用typeof、instanceof、constructor時要謹慎小心

  • typeof:JavaScript的一元操作符,用于以字符串的形式返回變量的原始類型,注意,typeof null也會返回object,大多數(shù)的對象類型(數(shù)組Array、時間Date等)也會返回object
  • constructor:對象(函數(shù))的內部原型屬性,它是可寫的(可以被重寫)
  • instanceof:JavaScript操作符,會在原型鏈中的構造器中搜索,找到則返回true,否則返回false(常用于判斷某一個對象是否是某個構造器或者其父類構造器的實例)
var arr = ["a", "b", "c"];
typeof arr;   // return "object" 
arr instanceof Array // true
arr.constructor();  // []

學會使用自調用函數(shù)

函數(shù)在創(chuàng)建之后直接自動執(zhí)行,通常稱之為自調用匿名函數(shù)(Self-Invoked Anonymous Function)或直接調用函數(shù)表達式(Immediately Invoked Function Expression )。比如,

(function(){
    // some private code that will be executed automatically
})();
(function(a,b){
    var result = a+b;
    return result;
})(10,20);

隨機從數(shù)組中取出一個元素

var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
var randomItem = items[Math.floor(Math.random() * items.length)];

從一個指定的范圍中取出一個隨機數(shù)

這個功能在生成測試用的假數(shù)據(jù)時特別有用。比如取一個指定范圍內的工資數(shù)。

var x = Math.floor(Math.random() * (max - min + 1)) + min;

生成一個從0開始到指定數(shù)字的序列

	
var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i++) < max;);  // numbers = [1,2,3 ... 100]

生成一個隨機的字母數(shù)字序列

function generateRandomAlphaNum(len) {
    var rdmString = "";
    for( ;rdmString.length < len; rdmString  += Math.random().toString(36).substr(2));
        return  rdmString.substr(0, len);
}

譯者注

toString()方法可以接受一個參數(shù)表示數(shù)字進制。而36進制剛好可以使用a-z和0-9這些字符。所以此方法可以用于生成簡單的隨機串。

打亂一個數(shù)字數(shù)組的順序

var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205]  */

這里采用了原生的排序函數(shù)sort(),此外我們還可以使用專門的工具庫來得到這一目的。

字符串去空格

像Java、C#、PHP這些語言都內置了trim()功能函數(shù)用于字符串去空格。但是Javascript沒有這個內置方法??梢酝ㄟ^下面的方法來得到此目的,

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g, "");
};

不過,在新的Javascript引擎中,已經內置支持了這個功能。

將一個數(shù)組追加到另一個數(shù)組中

var array1 = [12 , "foo" , {name "Joe"} , -2458];
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 值為  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

argruments轉換成數(shù)組

var argArray = Array.prototype.slice.call(arguments);

檢驗一個參數(shù)是否為數(shù)字

function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}

檢驗一個參數(shù)是否為數(shù)組

function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

如果toString()被重寫過的話,上面的方法就不行了。此時我們可以使用下面的方法,

Array.isArray(obj); // its a new Array method

如果在瀏覽器中沒有使用iframe,還可以用instanceof,但如果上下文太復雜,也有可能出錯。比如,

var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10]
// myArray 的構造器已經丟失,instanceof 的結果將不正常
// 不同iframe中的構造器是不能共享的
arr instanceof Array; // false

取出一個數(shù)組中的最大值和最小值

var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; 
var maxInNumbers = Math.max.apply(Math, numbers); 
var minInNumbers = Math.min.apply(Math, numbers);

清空一個數(shù)組

var myArray = [12 , 222 , 1000 ];  
myArray.length = 0; // myArray will be equal to [].

不用使用delete關鍵字來移除一個數(shù)組元素

應該使用splice方法而不是delete來移除一個數(shù)組元素。對一個數(shù)組元素使用delete會讓這個數(shù)組元素的值變?yōu)?code>undefined,并沒有將這個數(shù)組元素給刪除掉。

錯誤的用法,

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ]; 
items.length; // return 11 
delete items[3]; // return true 
items.length; // return 11 
/* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

正確的用法,

var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ]; 
items.length; // return 11 
items.splice(3,1) ; 
items.length; // return 10 
/* items 結果為 [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154, 119] */

注意,要想移除一個對象的屬性,應該采用delete方法。

可以通過操作數(shù)組長度length來截斷一個數(shù)組

與前面那個使用length清空數(shù)組的示例類似,我們可以使用length來截斷一個數(shù)組。

var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];  
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

除此之外,如果我們使用一個更大的值去重寫length,那么數(shù)組的長度將會改變,同時會用undefined填充新增的數(shù)組元素。

myArray.length = 10; // the new array length is 10 
myArray[myArray.length - 1] ; // undefined

在條件中使用&&||進行短語判斷

var foo = 10;  
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething(); 
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

||還用于給函數(shù)參數(shù)設置默認值,比如

function doSomething(arg1){ 
    arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set
}

使用map()對數(shù)組進行遍歷操作

var squares = [1,2,3,4].map(function (val) {  
    return val * val;  
}); 
// squares will be equal to [1, 4, 9, 16]

保留指定位數(shù)的小數(shù)點

var num = 2.443242342;
num = num.toFixed(4);  // num will be equal to 2.4432

注意,toFixed()方法返回的是字符串而不是一個數(shù)字。

浮點數(shù)計算問題

0.1 + 0.2 === 0.3 // is false 
9007199254740992 + 1 // is equal to 9007199254740992  
9007199254740992 + 2 // is equal to 9007199254740994

為什么呢?因為0.1+0.2等于0.30000000000000004。JavaScript的數(shù)字都遵循IEEE 754標準構建,在內部都是64位浮點小數(shù)表示,具體可以參閱這篇文章。

另外,你也可以使用toFixed()或者toPrecision()來解決這個問題。

譯者注

關于這個問題,博主也有一篇相關的文章,Javascript中浮點數(shù)的計算精度問題

使用for...in來遍歷對象的屬性

下面的代碼片段使用for...in來遍歷對象屬性,可以防止遍歷到對象原型鏈上的屬性。

for (var name in object) {  
    if (object.hasOwnProperty(name)) { 
        // do something with name                    
    }  
}

逗號運算符

var a = 0; 
var b = ( a++, 99 ); 
console.log(a);  // a will be equal to 1 
console.log(b);  // b is equal to 99

緩存臨時變量用于避免再次計算或者查詢

在使用jquery時,我們可以臨時緩存整個jq對象,比如

var navright = document.querySelector('#right'); 
var navleft = document.querySelector('#left'); 
var navup = document.querySelector('#up'); 
var navdown = document.querySelector('#down');

提前檢查傳入isFinite()的參數(shù)

isFinite(0/0) ; // false 
isFinite("foo"); // false 
isFinite("10"); // true 
isFinite(10);   // true 
isFinite(undefined);  // false 
isFinite();   // false 
isFinite(null);  // true  注意這里?。。?/code>

避免對數(shù)組進行負值索引

var numbersArray = [1,2,3,4,5]; 
var from = numbersArray.indexOf("foo") ;  // from is equal to -1 
numbersArray.splice(from,2);    // will return [5]

注意傳給splice的索引參數(shù)不要是負數(shù),當是負數(shù)時,會從數(shù)組結尾處刪除元素。

使用JSON來進行序列化和反序列化

var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} }; 
var stringFromPerson = JSON.stringify(person); 
/* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */ 
var personFromString = JSON.parse(stringFromPerson);  
/* personFromString is equal to person object  */

避免使用eval()和函數(shù)構造器

eval()和函數(shù)構造器(Function consturctor)的開銷都比較大,每次調用JavaScript引擎都要將源代碼轉換為可執(zhí)行的代碼。

var func1 = new Function(functionCode);
var func2 = eval(functionCode);

避免使用with()

使用with()語法會將變量注入到全局變量中。因此,如果有重名的變量,就會發(fā)生覆蓋或者重寫的問題。

避免使用for...in遍歷數(shù)組

錯誤的用法,

var sum = 0;  
for (var i in arrayNumbers) {  
    sum += arrayNumbers[i];  
}

更好的做法,

var sum = 0;  
for (var i = 0, len = arrayNumbers.length; i < len; i++) {  
    sum += arrayNumbers[i];  
}

除此之外,ilen是在for循環(huán)的第一個聲明中,二者只會初始化一次,這要比下面這種寫法快:

for (var i = 0; i < arrayNumbers.length; i++)

為什么呢?因為數(shù)組arrayNumbers的長度在每次遍歷的時候都會計算一次,這就造成了不必要的消耗。

注意,這個問題其實在最新的Javascript引擎中已經被修復了。

setTimeout()setInterval()傳遞函數(shù)而不是字符串更好

如果你給setTimeout()或者setInterval()傳遞字符串的話,那么它內部的執(zhí)行機制其實是和eval()是一樣的,這樣會比較慢。

錯誤的用法,

setInterval('doSomethingPeriodically()', 1000);  
setTimeout('doSomethingAfterFiveSeconds()', 5000);

正確的用法,

setInterval(doSomethingPeriodically, 1000);  
setTimeout(doSomethingAfterFiveSeconds, 5000);

使用switch/case來代替一坨if/else

當判斷有超過兩個分支的時候使用switch/case要更快一些,而且也更優(yōu)雅,更利于代碼的組織,當然,如果有超過10個分支,就不要使用switch/case了。

switch/case中使用數(shù)字范圍進行分界

其實switch/case中的case條件,還可以這樣寫:

function getCategory(age) {  
    var category = "";  
    switch (true) {  
        case isNaN(age):  
            category = "not an age";  
            break;  
        case (age >= 50):  
            category = "Old";  
            break;  
        case (age <= 20):  
            category = "Baby";  
            break;  
        default:  
            category = "Young";  
            break;  
    };  
    return category;  
}  
getCategory(5);  // will return "Baby"

為創(chuàng)建的對象指定原型

下面的示例演示了可以給定對象作為參數(shù),來創(chuàng)建以此為原型的新對象:

function clone(object) {  
    function OneShotConstructor(){}; 
    OneShotConstructor.prototype = object;  
    return new OneShotConstructor(); 
} 
clone(Array).prototype ;  // []

html轉義函數(shù)

function escapeHTML(text) {  
    var replacements= {'<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;'};                      
    return text.replace(/[<>&"]/g, function(character) {  
        return replacements[character];  
    }); 
}

不要在循環(huán)中使用try...catch...finally

try...catch...finally在捕獲一個異常時,會創(chuàng)建一個運行時環(huán)境的子作用域。而異常變量的生命周期僅限在這個運行時的子作用域。

譯者注

這里我們可以使用閉包來保存這個運行時的異常變量。

錯誤的用法

var object = ['foo', 'bar'], i;  
for (i = 0, len = object.length; i <len; i++) {  
    try {  
        // do something that throws an exception 
    } catch (e) {   
        // handle exception  
    } 
}

正確的用法

var object = ['foo', 'bar'], i;  
try { 
    for (i = 0, len = object.length; i <len; i++) {  
        // do something that throws an exception 
    } 
} catch (e) {   
    // handle exception  
}

使用XMLHttpRequests時注意設置超時參數(shù)

如果一個ajax請求長時間沒有響應,我們應該中止請求。否則瀏覽器將會一直等待。我們可以使用setTimeout()來做一個定時器,

var xhr = new XMLHttpRequest (); 
xhr.onreadystatechange = function () {  
    if (this.readyState == 4) {  
        clearTimeout(timeout);  
        // do something with response data 
    }  
}  
var timeout = setTimeout( function () {  
    xhr.abort(); // call error callback  
}, 60*1000 /* timeout after a minute */ ); 
xhr.open('GET', url, true);  
xhr.send();

除此之外,我們應該避免同時發(fā)送多個同步的ajax請求。

處理websocket超時

一般地,WebSocket連接創(chuàng)建后,如果30秒內沒有任何活動服務器端會對連接進行超時處理,防火墻也可以對單位周期內沒有活動的連接進行超時處理。

為了防止超時中斷,你需要每隔一段時間發(fā)送一個心跳數(shù)據(jù)(空字符串)以保持websocket連接。下面的兩個方法一個用于周期的發(fā)送心跳數(shù)據(jù)保持連接,一個是取消心跳數(shù)據(jù)包。

var timerID = 0;
function keepAlive() {
    var timeout = 15000;
    if (webSocket.readyState == webSocket.OPEN) {
        webSocket.send('');
    }
    timerId = setTimeout(keepAlive, timeout);
}
function cancelKeepAlive() {
    if (timerId) {
        cancelTimeout(timerId);
    }
}

keepAlive()方法應該被添加在webSOcket連接的onOpen()方法的最后,而cancelKeepAlive()添加在onClose()方法的最后。

記?。涸僮骺隙ū群瘮?shù)調用要效率高

比如,

在有些時候,相比下面這種用法

var min = Math.min(a,b); 
A.push(v);

可能在性能方面會比不上下面的做法

var min = a < b ? a : b; 
A[A.length] = v;

編碼時注意保持代碼的優(yōu)雅格式,上生產環(huán)境前做一些壓縮工作。

Javascript是一門很吊的語言,這里還有很多資源



以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號