45のJavaScriptプログラミングの注意事項、技巧大全書

15896 ワード

JavaScriptは世界に冠たるプログラミング言語で、Web開発、モバイルアプリケーション開発、アプリ開発、サーバ端末開発(Node.jsとWakanda)などに利用できます.JavaScriptはまだ多くの新米がプログラミング世界の最初の言語に足を踏み入れました.ブラウザの中の簡単なヒントボックスを表示するためにも、nodebotやnodruinoによってロボットを制御することができます.構造がはっきりしていて、性能が高いJavaScriptコードを作成できる開発者は、今や求人市場で最も人気のある人となっています.
この文章の中で、JavaScriptの技術、秘訣とベストプラクティスを共有します.ごく少数のほかに、ブラウザのJavaScriptエンジンでもサーバー端JavaScriptのインタプリタでも適用されます.
ここでの例示的なコードは、Google Chrome 30の最新版(V 8 3.0.27.115)でのテストに合格した.
1、初めて変数の割り当てをする場合は必ずvarキーワードを使用します.
変数が宣言されていないまま値を直接割り当てると、デフォルトは新しいグローバル変数として使用されます.
2、使用==置換==
==と!=オペレータは必要な場合に自動的にデータタイプを変換します.しかし==と!==いいえ、それらは同時に値とデータの種類を比較します.これによって、それらの比==和!速いです
 
  
[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
3、undefined、null、0、false、NaN、空の文字列の論理結果はいずれもfalse 4、行末にセミコロンを使用します.
実際にはやはりセミコロンを使ったほうがいいです.書くのを忘れても大丈夫です.ほとんどの場合、JavaScriptのインタプリタは自動的に追加されます.なぜセミコロンを使うかについては、文章JavaScriptの中のセミコロンの真相を参照してください.
5、オブジェクトコンストラクタを使う
 
  
  function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;
}
var Saad = new Person("Saad", "Mousliki");
6、typeof、instance of、contructor typeof:JavaScript 1元オペレータを注意深く使用して、変数の元のタイプを文字列で返すために使用します.注意してください.typeof nullもobjectに戻ります.ほとんどのオブジェクトタイプ(配列Aray、時間Dateなど)もojectに戻ります.
contructor:内部原型の属性はコードで書き換えることができます.
instance of:JavaScript操作子は、プロトタイプチェーン内のコンストラクタで検索し、見つけたらtrueに戻ります.そうでなければfalseに戻ります.
 
  
var arr = ["a", "b", "c"];
typeof arr;   // "object"
arr instanceof Array // true
arr.constructor();  //[]
7、自己起動関数を使用して作成後に直接自動的に実行され、通常は自己起動匿名関数(Self-Invoked Anonymous Function)または直接呼び出し関数式(Immeditely Invoked Function Expression)と呼ばれる.フォーマットは以下の通りです
 
  
(function(){
    //
})(); 
(function(a,b){
    var result = a+b;
    return result;
})(10,20)
8、配列からランダムにメンバーを取得する
 
  
var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
var  randomItem = items[Math.floor(Math.random() * items.length)];
9、指定範囲内の乱数を取得するという機能は、試験用のダミーデータを生成する際に特に数えられます.
 
  
var x = Math.floor(Math.random() * (max - min + 1)) + min;
10、0から指定値までの数字配列を生成する
 
  
var numbersArray = [] , max = 100;
for( var i=1; numbersArray.push(i++) < max;);  // numbers = [1,2,3 ... 100]
11、ランダムな文字数文字列を生成する
 
  
  function generateRandomAlphaNum(len) {
    var rdmString = "";
    for( ; rdmString.length < len; rdmString  += Math.random().toString(36).substr(2));
    return  rdmString.substr(0, len);
12、数字配列を狂わす順番
 
  
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* numbers [120, 5, 228, -215, 400, 458, -85411, 122205]  */
ここではJavaScriptに内蔵されている配列並び替え関数を使用しています.より良い方法は専門的なコードを使って(例えばFisher-Yatesアルゴリズム)、StockOverFlow上のこの議論を参照してください.
13、文字列をスペースに移動
Java、C胪とPHPなどの言語は専門的な文字列スペース関数を実現しましたが、JavaScriptにはないので、以下のコードでStringオブジェクト関数としてtrim関数があります.
 
  
String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};
新しいJavaScriptエンジンはすでにtrim()の原生が実現しました.
14、配列間の追加
 
  
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] */
15、オブジェクトを行列に変換する
 
  
  var argArray = Array.prototype.slice.call(arguments);
16、数字かどうかを検証する
 
  
  function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}
17、配列かどうかを検証する
 
  
  function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}
でも、toString()方法を書き換えられたら、だめです.以下の方法も使用できます.
 
  
  Array.isArray(obj); // its a new Array method
ブラウザでframeを使っていないなら、instance ofも使えますが、コンテキストが複雑すぎると、エラーが発生する可能性があります.
 
  
  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
// frame
arr instanceof Array; // false
18、行列の最大値と最小値を取得する
 
  
var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);
19、クリア配列
 
  
  var myArray = [12 , 222 , 1000 ]; 
myArray.length = 0; // myArray will be equal to [].
20、直接配列からdeleteまたはremove要素を使用しないでください.配列要素に直接deleteを使用すれば、実は削除していません.要素をundefinedに置くだけです.配列要素の削除にはspliceを使うべきです.
禁忌:
 
  
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 [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を使用できます.
21、length属性を使用して行列を切断します.
前の例では、length属性で空配列をクリアしても、配列を切断するために使用されます.
 
  
  var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ]; 
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].
同時に、length属性を大きくすると、配列の長さ値が増加し、undefinedを新たな要素として使用します.lengthは書き込み可能な属性です.
 
  
  myArray.length = 10; // the new array length is 10
myArray[myArray.length - 1] ; // undefined
22、条件で論理和または
 
  
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();
論理または関数パラメータのデフォルトなどのデフォルト値を設定するためにも使用できます.
 
  
function doSomething(arg1){
    arg1 = arg1 || 10; // arg1 will have 10 as a default value if it's not already set
}
23、map()関数方法によるデータ循環
 
  
  var squares = [1,2,3,4].map(function (val) { 
    return val * val; 
});
// squares will be equal to [1, 4, 9, 16]
24、指定された小数点以下の桁数を保留する
 
  
  var num =2.443242342;
num = num.toFixed(4);  // num will be equal to 2.4432
なお、toFixec()は文字列であり、数字ではない.
25、浮動小数点計算の問題
 
  
  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.3000万0004に等しいからです.JavaScriptの数字はすべてIEEE 754標準に従って構築されています.内部では64ビットの浮動小数点で表されています.具体的にはJavaScriptの数字はどのように符号化されているかを参照してください.
この問題はToFixed()とtoPrecsion()を用いて解決できます.
26、for-i n循環検査によって対象の属性は以下のような使い方で、反復時にオブジェクトの原型属性に入ることを防ぐことができます.
 
  
  for (var name in object) { 
    if (object.hasOwnProperty(name)) {
        // do something with name
    } 
}
27、コンマ操作子
 
  
  var a = 0;
var b = ( a++, 99 );
console.log(a);  // a will be equal to 1
console.log(b);  // b is equal to 99
28、計算およびクエリのための変数を一時的に記憶し、jQueryセレクタにおいて、DOM要素全体を一時的に記憶することができる.
 
  
  var navright = document.querySelector('#right');
var navleft = document.querySelector('#left');
var navup = document.querySelector('#up');
var navdown = document.querySelector('#down');
29、着信isFinite()のパラメータを事前にチェックする
 
  
  isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10);   // true
isFinite(undefined);  // false
isFinite();   // false
isFinite(null);  // true,
30、行列に負の値を使用してインデックスを作成することを避ける
 
  
  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に送るインデックスパラメータは負ではなく、負の値の場合は配列の最後から要素を削除します.
31、JSONで序列化と反秩序化
 
  
  var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* stringFromPerson "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */
var personFromString = JSON.parse(stringFromPerson);
/* personFromString person   */
32、eval()または関数コンストラクタeval()と関数コンストラクタのオーバーヘッドが大きいと使用しないでください.毎回起動すると、JavaScriptエンジンはソースコードを実行可能なコードに変換します.
 
  
  var func1 = new Function(functionCode);
var func2 = eval(functionCode);
33、with()の使用を避けるwith()は、変数をグローバルスコープに加えることができます.したがって、他の同名変数があると、混同しやすく、2つの値が上書きされます.
34、行列にfor-i-nを使わないでください.
 
  
  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]; 
}
もう一つの利点は、iとlenの2つの変数はforサイクルの最初の声明の中で、2つは一回だけ初期化されます.これは以下のような書き方より速いです.
 
  
  for (var i = 0; i < arrayNumbers.length; i++)
35、set Interval()とsetTimeout()に送る時関数を使って文字列ではなく、setTimeout()とset Interval()の文字列に送ると、彼らはevalのような方式で変換します.これはきっと遅くなります.だから使用しないでください.
 
  
setInterval('doSomethingPeriodically()', 1000); 
setTimeout('doSomethingAfterFiveSeconds()', 5000);
を使用します
 
  
setInterval(doSomethingPeriodically, 1000); 
setTimeout(doSomethingAfterFiveSeconds, 5000);
36、重ねたif/elseの代わりにswitch/caseを使う
二つ以上の分岐があると判断した時は、スウィッチ/caseを使うほうがもっと速くて、もっと優雅で、コードの組織に有利です.もちろん、10個以上の分岐があれば、switch/caseを使わないでください.
37、switch/caseに数字区間を使う
実は、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);  // "Baby"
38、使用対象を対象とした原型
以下のように、オブジェクトをパラメータとして指定し、これを元にした新しいオブジェクトを作成します.
 
  
  function clone(object) { 
    function OneShotConstructor(){};
    OneShotConstructor.prototype = object; 
    return new OneShotConstructor();
}
clone(Array).prototype ;  // []
39、HTMLフィールド変換関数
 
  
  function escapeHTML(text) { 
    var replacements= {"": ">","&": "&", "\"": """};                     
    return text.replace(/[<>&"]/g, function(character) { 
        return replacements[character]; 
    });
}
40、サイクル内でtry-catch-finallyを使わない
try-catch-finallyのcatch部分は実行時に異常を変数に与えます.この変数は実行時に作用するフィールド内の新しい変数として構築されます.
禁忌:
 
  
  var object = ['foo', 'bar'], i; 
for (i = 0, len = object.length; 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         // do something that throws an exception
    }
}
catch (e) {  
    // handle exception 
}
41、XMLHttp Requestsを使用する時、タイムアウトXMLHttpRequestsを設定することに注意して実行する時、長い間応答がない場合(例えば、ネットワーク問題などが発生した場合)、接続を中止すべきで、sets Timeout()を通じてこの仕事を完成することができます.
 
  
  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();
同時に注意したいのは、複数のXMLHttpRequests要求を同時に開始しないことです.
42、WebSocketの処理のタイムアウト
通常、WebSocket接続が作成された後、30秒以内に何の活動もない場合、サーバー側は接続をタイムアウトします.ファイアウォールは単位サイクルが活動していない接続をタイムアウトしてもいいです.
このような状況を防ぐために、一定時間おきに、サーバに空のメッセージを送信することができます.この需要は次の2つの関数によって達成でき、もう一つは接続をアクティブ状態に保つため、もう一つはこの状態を終了するために特化されている.
 
  
  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()メソッドの最後尾に置くことができます.cancel KeepAlive()はOClose()メソッドの最後尾に置くことができます.
43、時間は元のオペレータが関数の呼び出しより速いことに注意してください.VanillaJSを使用します.
 
  
  var min = Math.min(a,b);
A.push(v);
このようにして代替できます.
 
  
  var min = a < b ? a : b;
A[A.length] = v;
44、開発時はコード構造に注意し、オンライン前にJavaScriptコードを検査し、圧縮してJSLintやJSMinなどのツールを使ってコードを検査し、圧縮することができます.