2009-06-15 4 views
35

短いストーリー:私はPHPスタイルのゲッターが欲しい状況ですが、JavaScriptの中にあります。すべてのプロパティのJavaScriptゲッター

JavaScriptはFirefoxのみで動作しているため、Mozilla固有のJSは私にとってはOKです。

JSゲッターを作成するための唯一の方法は、名前を指定する必要がありますが、のゲッターをすべて定義したいと考えています。可能な名前です。これが可能かどうかは分かりませんが、私は非常に知りたいと思います。

+6

彼は魔法の関数__getと__setを参照していると想像してください。 – seanmonstar

答えて

44

最も近いのは__noSuchMethod__です。これはJavaScriptのPHPの__call()に相当します。

__noSuchMethod__を実装している可能性がありますが、__noSuchMethod__を使って(C#のように)プロパティを実装する方法がまだ見当たらないので、残念ながら__get/__ setと同等のものはありません。

var foo = { 
    __noSuchMethod__ : function(id, args) { 
     alert(id); 
     alert(args); 
    } 
}; 

foo.bar(1, 2); 
+1

私は実際には "メッセージを食べていない"という表現を作成しようとしていましたが、これは*正確に*です!ありがとう! – arantius

+0

私は "メッセージを食べていない"という概念を知らなかった。ありがとう –

+0

nowjsについてはどうですか? RPCスタイルのフレームワークを実際に動作させるためには、__set()と__get()のようなものを使用しなければなりません。私はそれがソースコードからどのように動作するかはわかりません。 – BMiner

1

PHPの__get()のような機能をお探しの場合は、Javascriptがそのような構造を提供しているとは思いません。

私が考えることができる最高のことは、オブジェクトの非関数メンバーをループし、それぞれに対応する "getXYZ()"関数を作成することです。危険な擬似っぽいコードで

for (o in this) { 
    if (this.hasOwnProperty(o)) { 
     this['get_' + o] = function() { 
      // return this.o -- but you'll need to create a closure to 
      // keep the correct reference to "o" 
     }; 
    } 
} 
5

Javascript 1.5getter/settersyntactic sugarを持っています。これは非常によく説明されています。here

これは一般的なWeb用ではありませんが、確かにFirefoxにもあります(サーバー側で使用したい場合は、Rhinoもあります)。

+5

__get()と__set()はあまりありません。 PHPのバージョンでは、まだ作成されていないものも含め、すべてのプロパティを監視できます。 – BMiner

5

あなたが実際に動作する実装が必要な場合は、undefinedに対する二番目のパラメータをテストしてarroundのあなたの方法を「ごまかす」ことができ、これはまた、あなたが実際に設定されたパラメータを取得使用することができますを意味します。

var foo = { 
    args: {}, 

    __noSuchMethod__ : function(id, args) { 
     if(args === undefined) { 
      return this.args[id] === undefined ? this[id] : this.args[id] 
     } 

     if(this[id] === undefined) { 
      this.args[id] = args; 
     } else { 
      this[id] = args; 
     } 
    } 
}; 
1

自分の解決策を構築するためにnickfsの回答を使用しました。私のソリューションは、すべてのプロパティに対して自動的にget_ {propname}とset_ {propname}関数を作成します。関数を追加する前に関数がすでに存在するかどうかをチェックします。これにより、デフォルトのgetメソッドまたはsetメソッドを、独自の実装で上書きするリスクを無視して、オーバーライドすることができます。

for (o in this) { 
     if (this.hasOwnProperty(o)) { 
      var creategetter = (typeof this['get_' + o] !== 'function'); 
      var createsetter = (typeof this['set_' + o] !== 'function'); 
      (function() { 
       var propname = o; 
       if (creategetter) { 
        self['get_' + propname] = function() { 
         return self[propname]; 
        }; 
       } 
       if (createsetter) { 
        self['set_' + propname] = function (val) { 
         self[propname] = val; 
        }; 
       } 
      })(); 
     } 
    } 
32

Proxyができます!私はこれが存在してとても幸せだ!答えはIs there a javascript equivalent of python's __getattr__ method?です。私の言葉で言い換えれば、

var x = new Proxy({},{get(target,name) { 
    return "Its hilarious you think I have "+name 
}}) 

console.log(x.hair) // logs: "Its hilarious you think I have hair" 

勝者のためのプロ! MDNドキュメントをチェックしてください:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

chrome、firefox、およびnode.jsで動作します。不利な点:IE - freakin IEでは動作しません。すぐに。

+0

これはEdgeでも動作します。特定のブラウザのバージョンについては、[caniuse.com](https://caniuse.com/#feat=proxy)を参照してください。 – styfle

13

あなたはES6でコーディングされている場合は、PHPよう見栄えの良いコードを持っているプロキシクラスを組み合わせることができます。

class Magic { 
    constructor() { 
     return new Proxy(this, this); 
    } 
    get (target, prop) { 
     return this[prop] || 'MAGIC'; 
    } 
} 

これはハンドラに結合するので、あなたではなく、ターゲットのこれを使用することができます。

注:PHPと異なり、プロキシはすべてのプロパティ要求を処理します。

let magic = new Magic(); 
magic.foo = 'NOT MAGIC'; 
console.log(magic.foo); // NOT MAGIC 
console.log(magic.bar); // MAGIC 

プロキシhttp://caniuse.com/#feat=proxyとクラスhttp://caniuse.com/#feat=es6-classをサポートするブラウザどの確認することができます。ノード8は、両方をサポートします。

+0

これは私が見つけた最高の答えです。 –

+0

^これは天才です – Ifnot

関連する問題