2011-04-16 12 views
0

インスタンス変数を指定すると、javascriptのプライベートメンバーにアクセスできますか?たとえば、javascriptのカプセル化 - プライベートメンバーにアクセスする方法はありますか?

function class Foo() { 
    var x=12; 
    // some other stuff 
} 
F = new Foo(); 
// how to get/set F.x? 

更新:クラスに特権メソッドがあるとします。プライベートメンバーにアクセスするために特権メソッドを乗っ取ることは可能ですか?

function class Foo() { 
    var x=12, y=0; 
    this.bar = function(){ y=y+1; } 
} 
F = new Foo(); 
// can I modify Foo.bar to access F.x? 
+0

から実際のオブジェクトにメソッドを注入することを可能にする注入方法を持っています。実際のコードではこれを行いません。 'F.x'はありません。' F.x'が必要な場合は 'this.x'を設定します。このようなことをエミュレートすることはできますが、ひどく設計されています。 – Raynos

+2

これは有効なJavaScriptコードではありません。 'class'キーワードはありません。 –

答えて

5

あなたが取得/ xの値を設定するprivileged methodが必要になります:

function Foo() { 
    var x = 12; 
    this.getX = function() { return x; }; 
    this.setX = function(v) { x = v; }; 
} 

var f = new Foo(), 
    g = new Foo(); 

f.getX(); // returns 12 
g.getX(); // returns 12 

f.setX(24); 

f.getX(); // returns 12 
g.getX(); // returns 24 

g.setX(24); 

f.getX(); // returns 24 
g.getX(); // returns 24 

ライブデモ:あなたの例ではhttp://jsfiddle.net/simevidas/j7VtF/

+0

クラスインスタンスを修飾して特権メソッドを動的に追加できますか? –

+0

@Andrewいいえ。コンストラクタ関数( 'Foo')がインスタンスオブジェクトを作成すると、' x'変数は失われます。コンストラクタ関数の実行中は**存在します。 –

+0

@AndrewB no。それはいけません。 – Raynos

0

、変数xはローカルにありますその関数が有効範​​囲外になるとその値は保持されません。次のようなオブジェクトの名前付きプロパティに値を割り当てることができますただし、次のオブジェクトに添付されているJavaScriptで

var Foo = function() { 
    this.x = 12; 
} 
var f = new Foo(); 
f.x; // => 12 
f.x = 123; // => 123 
0

プライベートメンバーが、彼らは外部にアクセスしているわけではなく、オブジェクトのにアクセス可能です自身のパブリックメソッド。彼らは私的な方法にアクセスすることができます。プライベートメソッドは、コンストラクタの内部関数です。

最終的にプライベートメンバーにアクセスするプライベート内部関数にアクセスするパブリック関数が必要です。

参考:Better way to access private members in Javascript

+0

オブジェクトではなくコンストラクタ関数のスコープにアタッチされます。 – Raynos

3

あなたは本当にはそのようなアクセスを望んでいた場合は、このような何かを行うことができますが、私は本当にはそれをお勧めしません:

function Foo() { 
    var x = 12; 
    this.runContext = function(f) { 
      return eval(f); 
    }; 
} 

var f = new Foo(); 
f.runContext('alert(x);'); 
+0

**ライブデモ:** http://jsfiddle.net/simevidas/j7VtF/1/ –

+0

'eval'は_devil_です。 – Raynos

+0

だから私は***本当に***それをお勧めしない:) – Ryan

2

あなたが書くことができますこれを達成するための特定のパターンのコード。

私はunderscoreの助けを借りて実証する予定です。

Live example

function Construct() { 
    this.foo = "foo"; 
    this._private = "bar"; 

    this.method = function() { 
     return 42; 
    }; 

    this._privateMethod = function() { 
     return "secret"; 
    }; 

    var that = this; 
    var inject = function(name, f) { 
     this[name] = _.bind(f, that); 
    }; 

    _.bindAll(this); 

    return { 
     "foo": this.foo, 
     "method": this.method, 
     "inject": inject 
    }; 
} 

var c = new Construct(); 
console.log(c.foo); // foo 
console.log(c.method()); // 42 
c.inject("foo", function() { 
    console.log(this._private); 
    console.log(this._privateMethod()); 
}); 
c.foo(); // bar, secret 

は基本的にここでは、2つのオブジェクトを持っています。実際のオブジェクトと、クライアントに渡すプロキシオブジェクト。プロキシは、プロキシのメソッドと変数を離れて実際の状態にアクセスすることはできません。

しかし、それはあなたが純粋にローカルクロージャのスコープへのアクセスを得るために、 `eval`を使用することができます_academic notion_としてプロキシ

関連する問題