2015-12-21 8 views
6

この質問は他の場所でも返答されるかもしれませんが、回答の検索方法がわかりませんでした。私はJavaScriptに慣れていないので、これは私が理解するための闘いです。私は、コンソールに次のように渡すと関数を返すChrome Devツール

function multiple(n) { 
    function f(x) { 
     return x * n; 
    } 
    return f; 
} 
var triple = multiple(3); 
var quadruple = multiple(4); 

次のコードを考えると

console.log(triple(5)); 

私は私が期待するものを手に入れる、それは、任意の数と同様に15である、それは意志3倍にする(または2番目の関数を使用する場合は4倍にする)。私は、次のコードを取得コンソールにトリプル入力すると

しかし:3以来...

f(x) { 
    return x * n; 
} 

べきではありませんコンソールリターンを...

f(x) { 
    return x * 3; 
} 

にコード化されます次のコードのおかげで機能:あなたが持っていた場合、それは同じように

var triple = multiple(3); 
+5

あなたの質問に答えて、3は「コード化されていません」というように、パラメータとして渡します。コンソールには、持っている機能のソースが表示されます。今あなたのソースにはx * 3があります。 – pvg

+0

これはいわゆる[クロージャ](https://www.wikiwand.com/en/Closure_(computer_programming))です。 「[レキシカル環境:共通理論]」(http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environment-common-theory/)も参照してください。 – user2683246

答えて

3

3は、ではありません。は、関数にハードコードされています。 fのコードは、3ではなく、変数nを参照しています。あなたのコードでは、そうn変更する方法がここでいくつかのコードをnを変更したが、想像する方法がないことが起こる:あなたはnを見ることができるように

function multiple(n) { 
    function f(x) { 
     return x * n; 
    } 
    function modifyN(newN) { 
     n = newN; 
    } 
    return { f: f, modifyN: modifyN }; 
} 
var resultFor3 = multiple(3); 
var triple = resultFor3.f; 
var modifyTripleN = resultFor3.modifyN; 

がハードコーディングされていません。それは他のどの変数とも変わりません。具体的な例では、multipleの終了後にnを変更する方法はありませんが、multipleの呼び出しによって作成されたクロージャの内部の値は、「ハードコードされた」ものではありません。

2

まあ、それは同じです:

var n = 3; 
    function f(x) { 
    return n * x; 
    } 

あなたは上記の機能が表示されますfログインしていますが、我々の場合n = 3には、スコープチェーンにnと呼ばれる最も近い変数から値を取得しますnそれを呼び出すときに、nの値が宣言されている場合グローバルスコープで

私はJSエンジンは、(あなたのケースでmultiple機能によって作成された閉鎖を)そのクロージャ内部n変数を格納する正確な方法を知っているが、どのような重要なことであることはクロージャ内の変数があるということですありません値ではなくreferenceによって保存されます。

2

tripleと入力すると、機能ののソースコードが表示されます。 3ので

が誤っステートメントで、次のコード

によって機能に符号化されます。あなたは関数のソースコードを変更していません。ソースコードを変更するには、関数全体を再定義する必要があります。あなたがやっていることはすべて、パラメータを渡すことだけです。コンソールから正しい出力が得られます。

は、実行時にそれだけでその変数(あるいはそのようなもの)のためのメモリアドレスに格納されているどのような値を探している、ハイレベルで、関数にパラメータを渡しているとき。しかし、関数のソースコードを書き換えているわけではありません。

関連する問題