端的に言えば、私はPHPスタイルのゲッターが必要な状況ですが、JavaScriptです。
私のJavaScriptはFirefoxでのみ実行されているので、Mozilla固有のJSで十分です。
JSゲッターを作成する唯一の方法は、その名前を指定することですが、all可能な名前のゲッターを定義したいと思います。これが可能かどうかはわかりませんが、知りたいです。
Proxy
ならできる!本当に嬉しいです!!答えはここにあります: Pythonの__getattr__メソッドに相当するJavaScriptはありますか? 。私の言葉で言い換えると:
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-異常なIEで動作しません。すぐに。
あなたが見つけることができる最も近いものは __ noSuchMethod __ であり、これはJavaScriptのPHPの__call()と同等です。
残念ながら、__ get/__ setに相当するものはありません。これは残念ですが、__ noSuchMethod__を実装できたのですが、__ noSuchMethod__を使用してプロパティを実装する方法(C#のように)はまだわかりません。
var foo = {
__noSuchMethod__ : function(id, args) {
alert(id);
alert(args);
}
};
foo.bar(1, 2);
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 をサポートするブラウザーを確認できます。 Node 8は両方をサポートします。
Javascript 1.5 には getter/setter構文糖度 があります。 John Resigによって非常によく説明されています here
Webで使用するには一般的ではありませんが、Firefoxには確かにあります(サーバー側で使用したい場合は、Rhinoも含まれます)。
機能する実装が本当に必要な場合は、2番目のパラメーターをundefined
に対してテストすることで、回避策を「だます」ことができます。これは、getを使用して実際にパラメーターを設定することもできることを意味します。
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;
}
}
};
私はニックネームの答えを使用して自分のソリューションを構築することになりました。私のソリューションは、すべてのプロパティに対して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;
};
}
})();
}
}
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"
};
}
}
プロパティを取得または設定するだけでなく、メソッドをプロキシする方法を探していたので、2つのプロキシを組み合わせたこのソリューションを思いつきました。
var original = {
foo : function(arg1, arg2){
return arg1 + " " + arg2;
}
};
var proxy= new Proxy(function() {}, {
get(target,name) {
return new Proxy(function() {}, {
apply: function(target, thisArg, argumentsList) {
return original[name](argumentsList[0], argumentsList[1]);
}});
}
});
log(original.foo('one', 'two'));
log(proxy.foo('one', 'two')); // this will execute original.foo('one', 'two')
https://jsfiddle.net/d4g0fx9e/
唯一の問題はこの行です:
return original[name](argumentsList[0], argumentsList[1]);
誰かがそれをより一般的にする方法を知っていますか?渡すパラメーターの数をハードコーディングする必要なし(「元の」を変更せずに)