JavaScriptコードの編纂中に様々な穴と埋め込み方法があります.

6280 ワード

穴という字は、ここでは「落とし穴」という意味です.JavaScriptの「弱言語」の性質によって、使用過程において異常にゆったりとした柔軟性がありますが、非常に簡単な「中手」です.これらの穴は往々にして隠れているので、両目をこすってこそ、JSを勉強し応用する道に順風満帆に行ける.
一、グローバル変数
JavaScriptは関数によってスコープを管理します.関数内部で宣言された変数はこの関数の内部だけで、関数の外部では使用できません.一方、大域変数はどの関数の外で宣言されていますか?それとも直接に簡単に使用されることを宣言していません.
「直接に簡単に使用すると宣言していない」とは、varキーを使用しないで変数を宣言することを意味します.これは、暗黙的にグローバル変数を発生させない方法が、変数をできるだけvarキーワードで宣言することであることを明らかにしました.
でも、varを使ったらokだと思いますか?この穴を見に来てください.
 
  
function foo() {
    var a = b = 0;
    // body...
}
あなたが望むのは二つの局所変数かもしれませんが、bは本物のグローバル変数です.whyBecauseは、右から左に演算されます.

     
  
function foo() {
    var a = (b = 0);
    // body...
}
したがって、bはグローバル変数です.
穴を埋めます:変数の声明、できるだけ一人で来る方がよくて、卸売りをしないでください.
二、変数宣言はまずピットを見にきます.

     
  
myName = "global";

function foo() {
    alert(myName);
    var myName = "local";
    alert(myName);
}

foo();
一見、私たちは2回のalertの結果を期待しています.それぞれ「global」と「local」ですが、実際の結果は「undefined」と「local」です.whyBecause変数は、同じスコープ(同じ関数)において、ステートメントは、スコープの上部に提示されて先に解析される.
したがって、上記のコードセグメントの実行挙動は、このようにすることができる.
 
  
function foo() {
    var myName;
    alert(myName); // "undefined"
    myName = "local";
    alert(myName); // "local"
}
もう一つのピットを使って、あなたが本当に理解しているかどうかをテストします.

     
  
if (!("a" in window)) {
    var a = 1;
}

alert(a);
a変数の宣言がコードの先頭に先行していますが、まだ値が与えられていません.次にif文に入り、判断条件において「a」in windowが成立している(aはグローバル変数として宣言されている)ので、判断文の計算結果はfalseであり、直接にif文が飛び出すので、aの値はundefinedとなります.
 
  
var a; // "undefined"
console.log("a" in window); // true

if (!("a" in window)) {
    var a = 1; //
}

alert(a); // "undefined"
ピットを埋めます:変数の声明、できるだけ手動でスコープのてっぺんに置く方がよくて、すぐに値を賦課することができない変数について、先に声明した後に値を賦課する手法をとることができます.
三、関数宣言
関数宣言もスコープの先頭に先んじて行われ、任意の表現とステートメントが解析され、値が求められます.

     
  
alert(typeof foo); // "function"

function foo() {
    // body...
}
比較してもいいです.
 
  
alert(typeof foo); // "undefined"

var foo = function () {
    // body...
};
このことがわかったあなたは、次の穴を踏みますか?

     
  
function test() {
    alert("1");
}

test();

function test() {
    alert("2");
}

test();
上記のコードの断片を実行して、2回目のパチンコの表示は全部「2」です.なぜそれぞれ「1」と「2」ではないですか?簡単で、testの声明はtest()より先に解析され、後者は前者をカバーするため、2回の実行結果はいずれも「2」である.
ピットを埋める:多くの場合、関数宣言の代わりに関数表現を使います.特にいくつかのステートメントブロックで.
四、関数式はまず名前付き関数式を見ます.当然、名前が必要です.例えば、

   var bar = function foo() { 
  
    // body...
};
関数名はその関数の内部にのみ表示されます.以下のようなピット:

     
  
var bar = function foo() {
    foo(); //
};

foo(); // :ReferenceError
補填坑:名前付き関数式(再帰およびdebugの用途を除く)は極力使わないでください.外部には関数名を使用しないでください.
五、関数の自己実行は、関数式に対して、後に()自己実行を加えて、括弧内でパラメータを伝えることができますが、関数宣言はできません.ピット:

     
  
// (1) , !
// ,
function foo(x) {
  alert(x);
}(1);
以下のコードセグメントはそれぞれ実行されます.(1)までは関数式ですので、ここの()はパケットオペレータではなく、演算子であり、呼び出し実行を表します.

   //            
  
var bar = function foo(x) {
  alert(x);
}(1);

// () function
(function foo(x) {
  alert(x);
})(1);

// ()
(function foo(x) {
  alert(x);
}(1));

// new
new function foo(x) {
  alert(x);
}(1);

// &&, ||, !, +, -, ~ ( ),
// ,
true && function foo(x) {
  alert(x);
}(1);
穴埋め:この穴の鍵は、様々な関数式の本質を明らかにすることです.
六、サイクル中のクローズドは以下のように展示されています.
 
  



   
    Document


   

when clicking links below, show the number of its sequence


   


 
  
var links = document.getElementsByTagName("ul")[0].getElementsByTagName("a");

for (var i = 0, l = links.length; i < l; i++) {
    links[i].onclick = function (e) {
        e.preventDefault();
        alert("You click link #" + i);
    }       
}
私たちはi番目のリンクをクリックすると、このシーケンスインデックスiの値が得られると予想していますが、実際にどのリンクをクリックしても、iはサイクルの最後の結果です.
理由を説明します.alertが呼び出された場合、forループ内の匿名関数式は、外部変数iへの参照(クローズド)を維持しています.この時点でループは終了し、iの値は「5」に変更されます.
穴を埋める:希望の結果を得るためには、変数iのコピーをサイクルごとに作成する必要があります.以下のプレゼンテーションで正しいやり方を示します.
 
  

   
    Document


   

when clicking links below, show the number of its sequence