2017-10-15 6 views
1

私はフロントエンドのWeb開発を自習しているグラフィックデザイナーです。私はHTMLとCSSに関するすべての記事を読み終えました。今私はJavaScript、特にMarijn Haverbeke(2011)のEloquent JavaScriptという本について読んでいます。彼は多くの説明せずにこの例を与える関数クロージャのトピックに関する:2つの値がJavaScriptの1つの引数で強制されますか?

function makeAdder(amount) { 
    return function(number) { 
     return number + amount; 
    }; 
} 

var addTwo = makeAdder(2); 
addTwo(3); 
-> 5 

私がここで理解していないが、それはの体内無名の機能function(number)内にあるとき、変数numberは、値が与えられている方法です機能makeAdder()makeAdder()関数は、1つの引数amountを受け入れます。これはmakeAdder(2)に値 "2"が与えられ、可変定義はaddTwoです。

しかし、その後、変数addTwoは今、これについては本当に奇妙いただきましたがaddTwo関数に与えられた3の値が何らかの形で使用されてしまった方法です、それは関数であるかのように、その後実行され、3の異なる値を与えています(2)、及び最後に5

+0

基本的に 'makeAdder(2)'が呼び出されると、それは新しい関数を返すだけで、その関数は_amount_(2に設定)の値を知ります。次に、新たに作成された関数が3を引数として呼び出されます。この時点で、 'addTwo'は_number + amount_(3 + 2)を合計することができます。 パラメータなしで 'makeAdder()'を呼び出すと、 'addTwo(3)'を試してみると、 'addTwo'は' undefined'値(_3_ + _undefined_ = _NaN_)を持つため、 'NaN'を返します。 – aUXcoder

答えて

0

3 ways to define a javascript class

Javascript.Info class

Wの最終値で終わる量の値とを加算し、変数numberための機能本体number + amountネストあなたがmakeAdderを呼び出すと、それは実際にはamountの値をとり、amount変数に入れます。は、関数を返します。内部返された関数はまだ評価されていません。

次にaddTwoを呼び出すと、パラメータnumberが内部関数に渡され、内部関数が評価され、応答が返されます。

コードにconsole.logステートメントを追加すると、割り当てと呼び出しの実行順序が明確になります。 外部関数を呼び出すと、それは文字どおりmakeAdderのオブジェクトの作成のように動作します。

クラスは関数キーワード、IIFEなどでjavascriptで作成されるため、クラスと呼んでいます。 makeAdderクラスのオブジェクトを作成すると、メンバ変数の値が2に割り当てられます。

この変数は、クラスのオブジェクトの内部に残り、makeAdderのオブジェクトのスコープ内に関数を戻すため、返されます関数。返された関数を評価すると、メンバ変数の値は内部関数に利用可能です。内部関数が評価されるとき、それはクラスのオブジェクトからのメンバ変数量の値とそれに渡されるパラメータからの数をとります。それを集計し、結果を返します。

function makeAdder(amount) { 
 
console.log("value assigned to amount is " + amount); 
 
    return function(number) { 
 
    console.log("value assigned to number is " + number); 
 
    return number + amount; 
 
    }; 
 
    } 
 

 
var addTwo = makeAdder(2); 
 
console.log("value assigned to amount, now calling inner function"); 
 
console.log(addTwo(3));

は、以下の

UPDATE:

私は以下のややクラスと互換性のある構造にあなたの機能を変更しました。2の値を達するに渡されるとき

  1. は、外側の関数(クラスの新しいオブジェクトが作成される)が評価され、2の値は、ユーザーによって提供される量の値からメンバ変数this.amtに設定されています(= 2)。

  2. このオブジェクトの内部に別の関数が定義されています。これはval、別の関数という名前です。それはただの定義であり、評価ではありません。

  3. 私はクラスのオブジェクトから関数としてvalを返します。そのため、オブジェクトから関数が返され、メンバー変数this.amtには既に値があります。

  4. 私はthis.val関数を下に2回呼び出します。構文を参照してください。なぜそれをパラメータで直接呼び出すことができますか?これは、評価の準備ができた関数を返すためです。

    数= 5、 、= 2量の関数を呼び出すと、その後= 8、数= 5

var a = function(amount) { 
 
     console.log("value assigned to amount is " + amount); 
 
    
 
     this.amt = amount; 
 

 
     this.value = function(number) { 
 
     console.log("value assigned to number is " + number); 
 
     return number + amt; 
 
     }; 
 
    
 
     return this.value; 
 
    } 
 
    
 

 
console.log(a(2)(5)); 
 
x = a(8); 
 
console.log(x(5));

BELOWさらに明確スニペットをSEE量と 1. axは関数として定義されます。クラスとして使用することを意図しています。

    1. これはメンバ変数 amount、最終的 numberamountの和を計算し、合計を返す関数 valを有しています。

    2. new axのオブジェクトが作成され、bに割り当てられます。デフォルト値で初期化されます。結果15.

    var ax = function() { 
     
          
     
          this.amount = 0; 
     
          
     
          this.val = function(number) 
     
          { 
     
          console.log("value assigned to number is " + number); 
     
          return number + this.amount; 
     
          } 
     
          
     
         } 
     
         
     
        var b = new ax(); 
     
        b.amount=7; 
     
        console.log(b.val(8)); 
     
    
    を取得します8.

  • として番号パラメータとVal関数を呼び出します7.

  • として量変数の値を設定し

  • LAST SNIPPET

    1. 斧は、関数を定義します。新しいオブジェクトを作成するときは、そのオブジェクトに変数を渡します。

    2. これは、classのオブジェクト内のthis.amountに値を割り当て、何も返しません。

    3. このオブジェクトの内部にある別の関数を呼び出すには、パラメータを1つ渡し、オブジェクトのメンバ変数から別のパラメータを使用します。

    4. 結果が表示されます。

    var ax = function(amt) { 
     
          
     
          this.amount = amt; 
     
          
     
          this.val = function(number) 
     
          { 
     
          console.log("value assigned to number is " + number); 
     
          return number + this.amount; 
     
          } 
     
          
     
         } 
     
         
     
        var b = new ax(6); 
     
        console.log(b.val(8));

  • 0

    これは、スコープと呼ばれるものの作品:関数内の引数は、関数の内部スコープされ、それが使用する関数全体を通じて入手できます意味(に似て変数宣言は、コードベース全体で再利用できます)。

    本質的には、引数amountは、新しい関数の内部であっても、関数全体で使用できるということです。

    あなたはこのような関数を考えることができます。

    function foo(n) { 
        return n + 2; 
    } 
    
    console.log(foo(5)); 
    
    // What you have done is basically equivalent to this function: 
    
    function foo() { 
        var n = 5; 
        return n + 2; 
    } 
    

    関数を呼び出すとき、それは関数内の変数を配置し、それを実行するようなものです。もちろん、コンソールに7と記録されます。

    今、私たちはmakeAdderにこれを適用することができます。

    function makeAdder(amount) { 
        return function(number) { 
        return number + amount; 
        }; 
    } 
    
    var addTwo = makeAdder(2); 
    
    // Turns into this: 
    
    function makeAdder() { 
        var amount = 2; 
        return function(number) { 
        return number + amount; 
        } 
    } 
    

    あなたはちょっと、これが起こっている場所を確認することができます - 、内側の関数があると評価amount = 2ので:私はこのことを理解していれば教えてください

    return function(number) { 
        return number + 2; 
    } 
    
    0

    正しく:

    コードの実行は、次の行から開始されます。

    var addTwo = makeAdder(2); 
    

    makeAdder()は引数2を引数 'parameter'に割り当てて実行されます。次に、コントロールは関数 'makeAdder'の本体に進みますが、突然値ではなく関数定義全体( 'function(number){..}')を返します。この時点で、makeAdder(amount)は実質的に関数(数値){...}になります。なぜなら、返されるのは単なる関数定義であり、実行ではないからです。これはvar定義を介してaddTwoに渡されます。この時点で、addTwoは "仮想"関数(数値){..}になり、割り当てられた引数が3のaddTwo(現在は "仮想"関数(数値))の実行が数値変数に渡されます"virtual" function()の内部にあります。そして、関数本体{return number + amount;}の内部で加算が行われ、合計5が生成されます。

    私が本当に驚くべきことと思うのは、(私が理解したことが正しいとすれば)変数 'amount'は本体が関数(数値)の定義を返すときにその値が消えないためです。 }を使ってAdder(amount)を作成します。あたかも彼が変数 'limbo'に入ったかのように、関数(number){...}がそれを呼び出すと、コードの世界に戻ってきました。私がここで学んだことは、トラック内の列車のようなコード内の異なるパスを横切って、コードが直線的に(完全ではなく)瞬時にコードを読み取ることです。 「オーバーラン」となっている。これは他のプログラミング言語の仕組みですか、これはjavascript固有のものですか?

    申し訳ありませんが、プログラマ以外の方法で説明すると、この方法でわかりやすくなります。

    +0

    私はあなたがクラス、オブジェクト、およびメンバ変数の概念を知っていれば幸いです。外部関数を呼び出すと、それは文字どおりmakeAdderのオブジェクトを作成するように動作します。クラスは関数キーワード、IIFEなどを介してjavascriptで作成されるため、クラスと呼んでいます。 makeAdderクラスのオブジェクトを作成すると、メンバ変数に2の値が割り当てられます。この変数は、クラスのオブジェクトの中に残り、makeAdderのオブジェクトのスコープ内にその関数を返します。返された関数を評価すると、メンバ変数の値... – Amit

    +0

    ......が内部関数で使用できます。内部関数が評価されるとき、それはクラスのオブジェクトからのメンバ変数量の値とそれに渡されるパラメータからの数をとります。それを集計し、結果を返します。 https://www.phpied.com/3-ways-to-define-a-javascript-class/ – Amit

    +0

    私はあなたの答えにあなたが提起したあなたの疑問に答えるために上記の私の答えを更新しました、それは長い答えです。それを通過する時間を取る。これらは非常に明確になります。 – Amit

    関連する問題