【転】JavaScriptは本当に分かりましたか?

4153 ワード

Soから、you think you know JavaScript?先端架設師として有名なBaranovasky
  • テーマ1 var a='he'
    if (!("a" in window)) {
        var a = 1;
    }
    alert(a);
    
  • 題目二var a=1,b=function a(x){x&a(--x);;;alert(a)
  • テーマ3
     function a(x) {
         return x * 2;
     }
     var a;
     alert(a);
    
  • テーマ四:function b(x,y,a){argments[2]=10;alert(a);}b(1,2,3);
  • テーマ5:function a(){alert}a.cal(null);助けの道具を借りないでください.答えを計算してください.答えは下にあります
  • 答え
    タイトル1
    if (!("a" in window)) {
        var a = 1;
    }
    alert(a);
    
    コードの意味:もしwindowに属性aが含まれていないなら、変数aを宣言して、1を割り当てます.alertが出てきた結果は1だと思うかもしれません.そして実際の結果は「undefined」です.なぜかを知るには、JavaScriptの3つの概念を知る必要があります.まず、すべてのグローバル変数はwindowの属性で、文var=1です.window.a=1に等しい.グローバル変数が宣言されているかどうかを次のように検出できます.
    "    " in window
    
    第二に、すべての変数宣言は範囲内のスコープの上部にあります.類似の例を見てください.
    alert("a" in window);
    var a;
    
    この時、声明はalertの後でも、alertがポップアップしたのは依然としてtrueである.これはJavaScriptエンジンが最初にすべての変数声明を墓参りしてから、これらの変数声明をトップに移動し、最後のコード効果はこのようなものである.
    var a;
    alert("a" in window);
    
    このように見えますが、なぜalertがtrueなのか分かりやすいです.第三に、この問題の意味を理解する必要があります.変数宣言は前倒しされましたが、変数の割当値はありません.この行のコードには変数宣言と変数の割当値が含まれています.ステートメントを次のコードに分割できます.
    var a;    //  
    a = 1;    //     
    
    変数宣言と赋値が一緒に使用されると、JavaScriptエンジンは自動的に変数宣言を前倒しするために二つの部分に分けられます.赋価のステップを前倒ししないのは、コードの実行に影響を与える可能性があるからです.ですから、これらの概念を知ったら、テーマのコードをもう一度振り返ってみます.
    var a;
    if (!("a" in window)) {
        a = 1;
    }
    alert(a);
    
    このように、タイトルの意味は非常にはっきりしています.まずaを声明して、aが存在しているかどうかを判断します.存在しないなら1になります.aは永遠にwindowに存在しています.この割当文は永遠に実行されないので、結果はundefinedです.早目にこの言葉はちょっと迷ってしまいました.
  • テーマ2
  • var a = 1,
        b = function a(x) {
            x && a(--x);
        };
    alert(a);
    
    このテーマは実際より複雑に見えるが、alertの結果は1である.ここには依然として3つの重要な概念があります.私たちは知っています.まず、テーマ1で変数宣言が実行コンテキストに入ると完了すると分かりました.第二の概念は関数宣言であり、すべての関数宣言はコード実行前に宣言が完了しました.変数宣言と同じです.関数宣言は以下のようなコードであることを明らかにします.
    function functionName(arg1, arg2){
        //   
    }
    
    以下は関数ではなく、関数式です.変数の割り当てに相当します.
    var functionName = function(arg1, arg2){
        //   
    };
    
    関数式が事前に行われていないことを明らかにします.通常の変数の値に相当します.第三に、関数宣言は変数宣言を上書きしますが、変数の割当値は上書きされません.これを説明するために、例を見てみます.
    function value(){
        return 1;
    }
    var value;
    alert(typeof value);    //"function"
    
    できるだけ早く変数宣言を以下のように定義しますが、変数valueは依然としてfunctionであり、つまりこの場合、関数宣言の優先度は変数宣言の優先度より高いですが、変数valueの割当値があれば、結果は全く違っています.
    function value(){
        return 1;
    }
    var value = 1;
    alert(typeof value);    //"number"
    
    このvalueは値を賦課した後、変数の賦値を初期化すると関数宣言を上書きします.問題に戻ります.この関数は有名な関数表現です.関数宣言のように変数宣言を上書きすることはできませんが、変数bは関数式を含んでいます.この関数式の名前はaです.ブラウザによってaという名詞の処理はちょっと違っています.IEではaを関数宣言として認識します.変数初期化によってカバーされています.つまりa(–x)を呼び出すとエラーが発生します.他のブラウザは関数内部でa(–x)を呼び出すことができます.基本的にIEでb(2)を呼び出すとエラーが発生しますが、他のブラウザはundefinedに戻ります.上記の内容を理解した後、このテーマをより正確で分かりやすいコードに変えるべきです.
    var a = 1,
        b = function(x) {
            x && b(--x);
        };
    alert(a);
    
    そうすると、なぜalertはいつも1なのかがよく分かります.
  • テーマ3
  • function a() {
        return 1 ;
    }
    var a;
    alert(a);
    
    このテーマは比較的簡単です.すなわち、関数宣言と変数宣言の関係と影響は、同じ名前の関数宣言に出会い、再定義されません.
  • テーマ4
  • function b(x, y, a) {
        arguments[2] = 10;
        alert(a);
    }
    b(1, 2, 3);
    
    このテーマについては、ECMAsCRIPT 262-3の仕様に説明があります.アクティブオブジェクトは、関数コンテキストに入るタイミングで作成され、関数のargments属性で初期化されます.argments属性の値はAgmentsオブジェクトです.Agmentsオブジェクトの具体的な定義については、ここを参照してください.ECMAScript argmentsオブジェクトです.
  • テーマ5
  • function a() {
        alert(this);
    }
    a.call(null);
    
    このテーマは最も簡単で、最も怪しいと言えます.このテーマについて、まず2つの概念を理解します.この問題は主にJavascriptのthisキーワードを考察し、ここを具体的に見ると:Javascript言語におけるthisキーワードの使い方について
    a.cal(null)についてECMAScript 262の仕様によると、最初のパラメータが導入されたオブジェクトの引数がnullまたはundefinedであれば、コール方法はグローバルオブジェクト(つまりwindow)をthisの値とする.ですから、いつnullに入っても、そのthisは全体の対象windowですので、このテーマは次のコードとして理解できます.
    function a() {
        alert(this);
    }
    a.call(window);
    
    だからポップアップの結果は「object Window」で分かりやすいです.
    ———まとめ:この5つのテーマは偏っているようですが、実際に考察するのは基本概念です.これらの基本概念を熟知してこそ、高品質のコードが書けます.
    var a = 'hello'
    
    [TOC]