この詳細のES6

この機能アンダー1.非矢印 

VAR OBJ = { 
            X: 0 
            F1:関数(){ 
                にconsole.log(この.X)。
            } 
        } 
        VARの F1 = obj.f1。
        VAR X = 1 

        obj.f1(); // 0 
        F1(); // 1

上記のコードは、obj.f1 f1と同じ機能を指すが、実行の結果が同じではありません。関数の本体は、このキーワードを使用するには、この違いの理由があります。我々はすべて知っているように、これは、関数が実行されている環境を指します。obj.f1ため()、OBJ環境におけるF1ランであるので、この点OBJ;これは地球環境を参照するように()のために、地球環境で実行されている)F1、F1(あります。したがって、2つの結果が同じではありません。

今度はそれについて考えてみましょう、なぜこれがそうですか?なぜobj.f1()は、obj環境が実行され、およびVAR f1の後に= obj.f1、f1は()グローバル環境で実行されますか?

その後の話を内部メモリのデータ構造から、一歩一歩、私たちは見てください。

VAR OBJ = { 
            X: 0 
            F1:関数(){ 
                にconsole.log(この.X)。
            } 
        }

上記のコードは、オブジェクトobjの変数に代入され、ジャバスクリプトエンジンは、オブジェクト、変数OBJに割り当て、オブジェクトのメモリアドレスを生成するために、メモリ内の最初であろう。言い換えれば、変数objがアドレスです。obj.xをリードバックするには、OBJエンジン最初のメモリアドレスを取得し、元のオブジェクトからのアドレスを読み出し、xプロパティを返します。


上記のように、各オブジェクトは、プロパティ名は、プロパティ記述オブジェクト、オブジェクト属性説明内の値に格納された属性値に対応しています。

属性値が関数である場合には、エンジンが個別に機能し、メモリに保存されている、属性プロパティの値に、アドレス割り当て関数f1を。関数は単一の値であるので、異なる環境(コンテキスト)で行うことができます

私たちは、関数内で、他の変数の現在の環境を参照することができます。だから、どのように現在の動作環境、それの関数内で取得するには?その答えは、これは、ということである。これは、現在のオペレーティング環境の機能を参照するために、その体内で機能するように設計されています。

今、私たちは最初の質問に答えることができ、obj.f1は、()は、objに格納されたアドレスでF1を見つけることです、それはOBJ環境下で行われる;および関数自体への直接のvar F1 = obj.f1、F1()の後にしたがって、f1は()グローバル環境で実行されます。

2.この機能の矢印

アロー関数は、この自分自身を作成しない、それだけで自分のスコープチェーンからこの1を継承します。この関数は、矢印は常に関数定義を有効にするオブジェクトを指してしまいます。

機能タイマ(){
     この .S1 = 0 この .s2 = 0 ;
    // 箭头函数 
    のsetInterval(()=> この .S1 ++、1000年);
    // 普通函数 
    のsetInterval(関数(){
         この .s2 ++ ; 
    }、 1000年)。
} 
VARのタイマ= 新しいタイマ()。
setTimeout(() =>はconsole.log( 'S1'、timer.s1)、3100)。  // S1:3 
のsetTimeout(()=>はconsole.log( 'S2'、timer.s2)、3100)。   // S2:0

上記のコードでは、二つの内部タイマーのタイマー機能を矢印機能と正常な機能を使用して、それぞれ、設けられています。結合は、この関数は、矢印、この通常の機能走行ポイント(即ち、グローバルオブジェクト)の範囲に定義されている範囲(すなわち、タイマ機能)。VARタイマー=新しいTimer()文が、この後に実行され、別の1000のMSは、関数定義開始矢印は、常にポイントどここの関数定義の開始オブジェクト、すなわちタイマー;通常の関数、理由はsetTimeout()ホスト機能の呼び出しで実行されるコードウィンドウオブジェクトにこの時点につながることができ、完全に独立した実行環境、上。だから、3100ミリ秒後、timer.s1は、3回更新し、決して一度timer.s2更新されて。

矢印関数は、このオブジェクトポイントが固定されています。実際の矢印は、それ自体にこの機能がないため、このような固定点は、これは、この外部符号ブロックの内部につながっています。それはこれを持っていないので、それは正確であるので、それはコンストラクタとして使用することはできません。

        VaRの名= 'ウィンドウのVaRの A = { 
            名: 'A' 
            ショー:() => { 
                にconsole.log(この.nameの)。
            } 
        } 
        A.show()。  // ウィンドウ

コードブロックのこの最も外側の点は、ウィンドウオブジェクトとなるように矢印、すなわち、無内部ショーこの機能により、上記のコードの関数として、このブロック内のこの層は、パーセルのない他の機能のため、です。だから、最終的に出力ウィンドウ。

だから、それは永遠にどのように変化するかをバインドしますか?

        VaRの名= 'ウィンドウのVaRの A = { 
            名: 'A' 
            ショー:関数(){
                 VAR S =()=>はconsole.log(この.nameの)。
                リターン秒; 
            } 
        } 
        VARのショー= A.show()。
        ショー(); // VARの B = { 
            名:B 
        } 
        show.call(B)。   // 
        show.call()。    // A
        

これは、常に者が分析でき、オブジェクトAを指すんでした:

矢印の関数であるオリジナルコードのショーは、これを所有していない;コードは改正後、機能がショーにある矢印機能の範囲は、ショーは通常の関数であり、これを自分自身を持って、関数呼び出しの時に有効になります。A.show()の目的は、Aである指さ したがって、それはA点である。この機能での矢印

 

おすすめ

転載: www.cnblogs.com/ly2019/p/11006188.html