フロントエンドの基礎ステップ(六):chrome開発者ツールでの関数呼び出しスタック、作用ドメインチェーンとクローズド

6185 ワード

先端開発において、ブレークポイントデバッグという非常に重要なスキルがあります.
chromeの開発者ツールでは、ブレークポイントデバッグによって、JavaScriptの実行過程を観察するのに非常に便利です.直感的な感知関数は、スタック、作用ドメインチェーン、変数オブジェクト、クローズド、thisなどの重要な情報の変化を呼び出します.したがって、ブレークポイントの調整は、高速位置決めコードのエラーに対して、コードの実行過程を迅速に知るために非常に重要な役割を果たしています.
もちろん、JavaScriptのこれらの基礎概念(コンテキスト、変数オブジェクト、クローズド、thisなどを実行する)について理解が足りないなら、ブレークポイントを徹底的に把握してデバッグするのは難しいかもしれません.しかし、幸いにも前のいくつかの記事では、これらの概念を詳細に概説していますので、このスキルをマスターするには、皆さんにとっては比較的楽です.
この文章の主な目的はブレークポイントのデバッグに対する学習を通して、クローズドに対する理解を深めることです.
一、基礎概念の回顧
関数は実行を呼び出すと、現在の関数の実行コンテキストを作成します.この実行文脈の作成段階では、変数オブジェクト、作用ドメインチェーン、クローズド、this指向がそれぞれ決定されます.JavaScriptプログラムには、一般的に、複数の関数があります.JavaScriptエンジンは、関数を使用してスタックを呼び出して、これらの関数の呼び出し順序を管理します.関数コールスタックの呼び出し順序はスタックデータ構造と一致している.
二、ブレークポイントデバッグツールを認識する
できるだけ新しいバージョンのchromeブラウザで、chromeブラウザの開発者ツールを呼び出します.
            ->      ->       -> Sources
画面は図のようです
私のデモの中にコードをap.jsに入れてindex.で導入します.私たちはしばらくスクリーンショットの中の赤い矢印のところに注目したいです.一番右側の上に、アイコンの列があります.彼らを使って関数の実行順序を制御することができます.左から右に行くと、次のようになります.
  • reume/pause script execution回復/一時停止スクリプト実行
  • step over next function cal
  • 跨ぎ、実際の表現は関数に遭遇しない場合、次のステップを実行します.関数に遭遇すると、関数に入らずに次のステップを実行します.
  • step into next function cal
  • 踏み込み、実際の表現は関数に遭遇しない場合、次のステップを実行します.関数に出会うと、関数に入ってコンテキストを実行します.
  • step out of current function
  • 現在の関数を出力
  • deactivate breakpoints
  • ブレークポイントを停止
  • don't pause on exceptions
  • 異常捕獲を停止しない
    その中で乗り越えて入ります.飛び出すのは私が一番多く使う三つの操作です.
    上の図の右側の2番目の赤い矢印は、関数コールスタックを指しています.ここでコード実行中のスタックの変化が表示されます.
    右の3番目の赤い矢印はスコープを指し、ここでは現在の関数のスコープを示します.ここでLocalは現在の局所変数オブジェクトを表し、Cloureは現在の作用領域チェーンにおける閉ループを表している.ここの作用領域チェーンの展示によって、私たちは一例では誰がクローズドなのかを直感的に判断できます.
    三、ブレークポイント設定
    コードの行数が表示されているところをクリックすると、ブレークポイントを設定できます.ブレークポイントの設定には以下のような特徴があります.
  • は、個々の変数宣言(与えられていない場合)で、関数宣言の行にブレークポイントを設定できません.
  • ブレークポイントを設定してからページを更新します.JavaScriptコードはブレークポイントの位置で実行を停止します.その後、上述したいくつかの操作を使ってデバッグを開始します.
  • あなたが複数のブレークポイントを設定すると、chromeツールは自動的に最初に実行されたブレークポイントから実行すると判断しますので、ブレークポイントを設定すればいいです.
  • 四、実例
    次に、いくつかの例を借りて、ブレークポイントデバッグツールを使って、私達のデモ関数を見てみます.実行中の具体的な表現です.
    // demo01
    
    var fn;
    function foo() {
        var a = 2;
        function baz() {
            console.log( a );
        }
        fn = baz;
    }
    function bar() {
        fn();
    }
    
    foo();
    bar(); // 2
    下を読む前に、私たちは立ち止まって考えてもいいです.この例では、誰が閉じていますか?
    これは『あなたが知らないjs』から来た例です.ブレークポイントを使ってデバッグする過程で、chromeブラウザで理解しているクローズドはこの例で理解しているクローズドとあまり一致していないことが分かりました.私個人はchromeの中の理解にもっと傾いています.
  • 第一歩:ブレークポイントを設定し、ページを更新します.
  • 第二ステップ:上の図の赤い矢印が指すボタン(step into)をクリックすると、このボタンの役割はコードに従って順次実行され、次のステップに進みます.クリック中に、下のcall stackとscopeの変化と関数の実行位置の変化に注意します.
  • ステップ1で実行します.関数が前の例に実行されると
    chromeツールの理解では、foo内部で宣言されたbaz関数が起動時に変数aにアクセスしたため、fooはクローズドとなっていることが分かります.これは私たちが学んだ知識とは違っているようです.『あなたの知らないjs』という本の中の例の中の理解を見てみましょう.
    本の中の注釈は明らかに分かることができます.作者はfnがクローズドだと思っています.つまりbazです.これはchromeツールとは明らかに違います.
    みんなから推賞されている「JavaScript高級プログラミング」では、このように定義されています.
    ここでchromeで理解しているクローズドは、私が読んでいるこれらの本の中のクローズドとは違っています.実は前に闭包分析についての文章の中で、私はすでにこのようなことを解読しました.クローズド詳細
    クローズドパケットは、実行コンテキスト(コードA)と実行コンテキストで作成された関数(コードB)とが共同で構成される特殊なオブジェクトです.
    Bが実行されると、A中の変数オブジェクトの値にアクセスすると、クローズドが発生します.
    大多数の理解の中で、多くの有名な書籍が含まれています.文章の中では関数Bの名前でここで作られたクローズドを指しています.chromeでは、コンテキストAを実行する関数名で、クローズドを指す.
    demo 01の例を修正して、非常に興味深い変化を見てみます.
    // demo02
    var fn;
    var m = 20;
    function foo() {
        var a = 2;
        function baz(a) {
            console.log(a);
        }
        fn = baz;
    }
    function bar() {
        fn(m);
    }
    
    foo();
    bar(); // 20
    この例はdemo 01に基づいて、baz関数からパラメータを入力して印刷します.呼び出し時にグローバル変数mを入力します.出力結果は20になります.ブレークポイントを使ってデバッグして、スコープを見てみます.
    結果はちょっと意外ですが、クローズドがなくなりました.スコープにはfooが含まれていません.私たちが理解しているのとはまた違っているようです.この比較によって,クローズドの形成には二つの条件が必要であると判断できた.
  • は、関数の内部に新しい関数を作成します.
  • 新しい関数が実行されると、関数の変数オブジェクトにアクセスします.
  • もっと面白いのがあります.
    例を続けてみましょう.
    // demo03
    
    function foo() {
        var a = 2;
    
        return function bar() {
            var b = 9;
    
            return function fn() {
                console.log(a);
            }
        }
    }
    
    var bar = foo();
    var fn = bar();
    fn();
    この例では、fnはfoo中のa変数だけにアクセスしていますので、そのクローズドはfooだけです.
    demo 03を修正して、私達はfnの中でbarの中のb変数にもアクセスしてみます.
    // demo04
    
    function foo() {
        var a = 2;
    
        return function bar() {
            var b = 9;
    
            return function fn() {
                console.log(a, b);
            }
        }
    }
    
    var bar = foo();
    var fn = bar();
    fn();
    この時、閉包は二つになりました.それぞれbar、fooです.
    私たちは知っています.モジュールに閉じ込められたアプリケーションがとても重要です.そこで、モジュールの例を紹介します.ブレークポイントツールで観察してみます.
    // demo05
    (function() {
    
        var a = 10;
        var b = 20;
    
        var test = {
            m: 20,
            add: function(x) {
                return a + x;
            },
            sum: function() {
                return a + b + this.m;
            },
            mark: function(k, j) {
                return k + j;
            }
        }
    
        window.test = test;
    
    })();
    
    test.add(100);
    test.sum();
    test.mark();
    
    var _mark = test.mark;
    _mark();
    注意:ここのthisはObjectまたはWindowとして表示されています.大文字で始まると、彼らは実例的な構造関数を表しています.実際にはthisは指す具体的な例です.
    test.markがクローズドになるのは、以下の補足例(demo 07)と同じです.
    私たちはまた、これらの問題を理解するために、ポイントの調整方法を組み合わせることができます.常にthisの指向を観察し、実際の開発とデバッグにおいて非常に有用である.
    // demo06
    
    var a = 10;
    var obj = {
        a: 20
    }
    
    function fn () {
        console.log(this.a);
    }
    
    fn.call(obj); // 20
    最後に一つの例を追加し続けます.
    // demo07
    function foo() {
        var a = 10;
    
        function fn1() {
            return a;
        }
    
        function fn2() {
            return 10;
        }
    
        fn2();
    }
    
    foo();
    この例は他の例とは違っています.fn 2はfooの変数にはアクセスしていませんが、foo実行時はまだクローズドになりました.fn 1の声明を削除すると、クローズドが出なくなります.
    この特殊な例を組み合わせて、このように閉包を定義することができます.
    クローズドとは、このスコープによって閉じられた変数(a)、関数、またはクローズドなどを呼び出すことができる関数(fn 1)を含む、このような作用領域を指す.通常は、クローズドに対応する関数によって、クローズドへのアクセスを得る.
    もっと多くの例は、みんな自分で試してもいいです.つまり、ブレークポイントを使ってデバッグしてから、コードの実行過程を簡単に知ることができます.これは急速な位置決めミスに対して、他人のコードを早く知るために非常に大きな助けがあります.みんなは必ず実践に着手して,それをマスターさせなければならない.
    最後に、以上の模索状況に基づいて、再度閉包をまとめます.
  • クローズドは、関数が実行されると確認されて作成されたものです.
  • クローズドの形成は、ロールドメインチェーンのアクセス順序に直接関係している.
  • は、内部関数のみが上位の作用するドメインチェーン内の変数オブジェクトにアクセスしたときに、クローズドパケットが形成されるので、関数内部の変数にアクセスするために、クローズドパケットを利用することができる.
  • 皆さんも私が提供したこの方法によって、他の例に対してもっと多くのテストを行うことができます.もし私の結論が間違っていることを発見したら、ご指摘を歓迎します.
    先端ベースステップシリーズカタログ