1

私の目標は、クリーンなコードを書きながらクロージャーを使用することです。私が気づいたことの 1 つは、匿名関数の 1 つが複数のケースで必要とされるため、どういうわけか常に同じことを繰り返してしまうことです。

この目標のために、これらの繰り返される関数をオブジェクトに格納して、後で再利用できるようにしたいと考えています。

さて、私の質問に。この例を作成しましたhttp://jsfiddle.net/tiagoespinha/tTx64/yがnullであるため、アラートは発生しません。

ただし、関数をインライン化すると、すべて正常に動作しますhttp://jsfiddle.net/tiagoespinha/tTx64/1/

これを回避するトリックはありますか?最初の例でどのように動作させることができますか? 変数yはまだそこにあるのに、なぜ JS はそれをキャッチできないのでしょうか?

4

4 に答える 4

1

独自の変数(y)と共有関数を持つオブジェクトが必要です。

本当に必要なのはおそらくプロトタイプです。

function Holder() {
   this.y = 5;
   this.myFn();
}
Holder.prototype.myFn = function() {
    alert("The value of the closure var is " + this.y);           
}
new Holder();

クロージャだけでOOPを再構築しようとしないように、オブジェクト指向JavaScriptの概要を読むことをお勧めします。

于 2012-11-25T10:01:05.677 に答える
1
//our constructor, each instance will carry a y of 5
function Proto() {
    this.y = 5;
}

//a shared function for all instances
Proto.prototype.returnedFn = function() {
    alert("The value of the closure var is " + this.y);
}

//just a wrapper for the new instance call.
//I just like it this way to avoid using "new" when making instances
function newFn() {
    //return a new instance
    return new Proto();
}

//test it out
newFn().returnedFn();
newFn().returnedFn();
于 2012-11-25T10:03:54.423 に答える
1

最初の例では、何らかの動的スコープが機能する必要があります。Javascript は静的スコープです。

クロージャーにより、関数は、定義されているスコープからいくつかのローカル変数をキャプチャできます。 Holder.myFnvariable を含むスコープでは定義されていませんy

また、関数のすべてのインスタンスには独自のクロージャがあることに注意してください。したがって、関数を一度定義してy、異なるコンテキストで異なる を参照させることはできません。(2 番目の例では、を呼び出すたびに内部関数が定義されるnewFnため、多数のインスタンスが存在し、それぞれが の独自のコピーを持ちますy。)

于 2012-11-25T10:35:50.223 に答える
0

また、調査結果を報告するために、自分の質問に回答を追加します。

提供された他のソリューションに基づいて、部分的に OOP ソリューションを使用して、クロージャーも使用する別の方法を見つけました。

// Object prototype which takes an argument 
function MyObj(abc) {

    // Declare function using a closure
    // and thus being able to use the argument
    this.myFn = (function(){
        return function() {
            alert("abc is " + abc);
        };
    })();                
}

// Then we can simply create an object with the
// desired argument and the function will behave as expected
var v = new MyObj(10);
v.myFn();

おそらく、値をオブジェクトにローカルに保存したくないことを省略したため、誰もこのソリューションを提供しなかったと思います。いくつかの値を渡し、それらを 1 つの関数で使用してから、オブジェクトを削除したいだけです。

この場合、純粋な OOP ソリューションはやり過ぎだと思います。

とにかく、提案されたすべての解決策に感謝します! </p>

于 2012-11-25T13:53:21.603 に答える