2

現在のプロジェクトで John Resig の継承実装を使用していますが、サブクラスが親のクロージャ変数も継承 (アクセス) する方法があるかどうか疑問に思っていました...

たとえば、次のクラスを作成します

var Foo = (function() {  
  var p = "im p";

  var Foo = Class.extend({  
    getp : function() {
       return p;
    }
  });

  return Foo;
})();

これで、Foo クラスはクロージャー内の変数 p にアクセスできるようになりました。Fooのサブクラスもそうです...

var Bar = Foo.extend({});  
var bar = new Bar;
bar.getp(); // "im p"

bar.getp は p にアクセスできる Foo.getp を呼び出すだけなので、これは当然のことです。ただし、bar.getpを上書きすると

var Bar = Foo.extend({
  getp : function() {
    return p;
  }
});

bar.getp() を実行すると、bar にアクセスできないため、p is undefined がスローされます

p を bar にアクセスできるようにするいくつかの方法を考えていますが、少し扱いに​​くいと思います。これを実現する最もクリーンな方法だと思います。

4

2 に答える 2

2

pvariable は自己実行無名Foo関数のスコープでのみ定義されているため、取得する方法はありません。

これは、宣言されたクラスでのみ使用できるプライベート メンバーと考えてください。

それを取得するだけでよい場合は、次のようにすることができます。

var Bar = Foo.extend({
  getp : function() {
    var p = Foo.prototype.getp.call(this);
    return p;
  }
});
于 2012-09-10T03:21:40.400 に答える
2

クロージャースコープは、関数が定義されたときにスコープ内にあるもので構成されます。この場合、pは最初の定義時にはスコープ内にありますgetpが、2 番目の定義時にはスコープ内にありませんgetp。したがって、参照することはできませんpp実際、最初のメソッドによって参照されるは、実際にはすべてのオブジェクト (およびそのサブクラス) に対してgetp普遍的であることに気付いたかもしれません。Foo

JavaScript は、「プライベート変数」にはあまり適していません。一般に、開発者は、継承が必要ない場合はクロージャー スコープの変数を使用するか、継承が必要な場合は、次のようにアンダースコアを追加するなどの何らかの規則を使用することになります。

var Foo = Class.extend({  
    _p : "i'm p",
    getp : function() {
        return this._p;
    }
 });

次に、問題なくサブクラス化できます。

var Bar = Foo.extend({  
    getp : function() {
        return this._p;
    }
});

さて、あなたの例はかなり不自然であり、少し無意味になるように工夫されていることにも注意してください。getp()つまり、単に返すだけのものでオーバーライドするのはなぜpですか? あなたの意図が実際にプライベートな静的プロパティを作成することであった場合、pあなたが持っているものはうまくいくはずです。pサブクラスでアクセスしたい場合は、次getpのように、アクセスできるメソッドを使用する必要があります。

var Bar = Foo.extend({  
    getpete : function() {
        return Foo.getp() + "ete"; 
        //You can also use this.getp() if you want, there's no difference.
    }
});

それが役立つことを願っています!

于 2012-09-10T03:37:47.663 に答える