2017-02-06 26 views
0

誰かが次のコードを説明できますか?内部関数が同じ親関数内の "内部"変数にアクセスしないのはなぜですか?それでも、同じ変数をピア関数と共有しているようです。子関数内から "this"を使用して親関数の "inside"変数にアクセスできることは知っていますが、なぜこれが必要なのか困惑しています....私がおそらくもっと静的なものが必要でしょうか?私はJavaScriptの機能をラップするためにこのパターンを使用してきましたが、変数のカプセル化(より静的なもの)のこの挑戦を避ける、より良い/より簡単なパターンがあるのだろうかと思います。あなたの洞察をいただきありがとうございます。範囲内の関数内のjavascript変数の範囲

var wrap = function() { 
 
    var inside = null; 
 

 
    function showInside() { 
 
    console.log(inside); 
 
    } 
 

 
    function changeInside() { 
 
    console.log(inside); 
 
    inside += 'test'; 
 
    } 
 

 
    return { 
 
    inside: inside, 
 
    showInside: showInside, 
 
    changeInside: changeInside 
 
    }; 
 
}(); 
 

 
wrap.changeInside(); 
 
wrap.showInside(); 
 
wrap.changeInside(); 
 
wrap.showInside(); 
 
console.log(wrap.inside);

+0

質問は正確には何ですか? –

+1

あなたの問題は、関数とはまったく関係ありません。以下はあなたが見ているものの簡略版です: 'var foo = 42; var obj = {foo:foo}; foo = 21; console.log(obj.foo); ' JavaScriptは**値渡し**です。 '{foo:foo}'は 'foo'の値の* copy *をプロパティ' foo'に割り当てます。 –

+0

JavaScriptで値渡し**と言っても、参照を値として渡すことができるので混乱していると思います。 'foo'がオブジェクトであれば、オブジェクトのコピーではなくオブジェクトへの参照のコピーを割り当てます。 –

答えて

6

なぜ内部関数は、同じ親関数内で「内部」変数にアクセスしない - まだ彼らは、ピア機能と同じ変数を共有するように見えますか?

があります。

あなたが言うときので、あなたは混乱している:

return { 
    inside:inside, 

あなたは新しいオブジェクトのプロパティinsideに変数insideをコピーします。これは、オブジェクトを作成するときに行います。

後で変数の値を変更すると、それは財産との関連、それほど更新されません性質を持っていません。


プロパティに変数をリンクするには、getter/settersを使用する必要があります。

var wrap = function() { 
 
    var inside = null; 
 

 
    function showInside() { 
 
    console.log(inside); 
 
    }; 
 

 
    function changeInside() { 
 
    console.log(inside); 
 
    inside += 'test'; 
 
    } 
 

 
    return { 
 
    get inside() { 
 
     return inside; 
 
    }, 
 
    set inside(value) { 
 
     inside = value; 
 
    }, 
 
    showInside: showInside, 
 
    changeInside: changeInside 
 
    }; 
 

 
}(); 
 

 
wrap.changeInside(); 
 
wrap.showInside(); 
 
wrap.changeInside(); 
 
wrap.showInside(); 
 
console.log(wrap.inside);

+0

私の混乱を解消するためにあなたの助けをありがとう! :-) – user6096790

0

私はあなたが概念的な問題を抱えていると思います。見てみましょう:そこ()続く

var wrap = function(){ 
    ... 
}(); 

はあなたがが機能を呼び出し、wrapその戻り値を代入している、wrapに機能を割り当てていないことを意味します。

戻り値は、あなたがwrap.insideで変数inside

return { 
    inside:inside, //The value of inside (null) 
    showInside:showInside, //The local function showInside 
    changeInside:changeInside //The local function changeInside 
}; 

見えない持っている関数が呼び出されたときに、あなただけの価値を持っています。

まず、次の手順を実行する必要があります

var wrap = function() { 
    ....  
    return this; //Return the object itself 
}(); 

そして、関数内の変数や関数は、関数の範囲に属します。そのスコープの外からはアクセスできません。だから、代わりにプロパティを定義するかもしれません。

var wrap = function() {  
    this.inside = 1; //property 

    var insideVar = 2; //variable 

    this.showInside=function() { //property (with a function assigned to it) 
     console.log(insideVar); 
     console.log(this.inside); 
    }; 

    this.changeInside=function() { //property 
     insideVar+=2; 
     this.inside+=1; 
    }; 

    return this; 
}(); 

そして今:

console.log(wrap.inside); //-> 1 
console.log(wrap.insideVar); //-> undefined 
console.log(wrap.changeInside()); 
console.log(wrap.showInside); //-> 4 and 2 
console.log(wrap.inside); //-> 2 

は差が明らかであると思います。そうでなければ、もっと説明を求めるだけです。

+0

とにかく助けてくれてありがとう!私はあなたが私のコードと理解で同じ問題を見つけたと思うが、受け入れられた答えは私のためにもっと明確で役立った。私が使用してパターンを好む主な理由は、カプセル化と、関数内でカプセル化しているコードから関数と変数を選択的に隠して公開する機能です。私は、カプセル化のためにストレートオブジェクトを使い始めましたが、多くの必要な機能や変数が露出していて、オブジェクト内でのみ有用で必要なものがあるため、管理が非常に面倒で管理が困難でした。 – user6096790