web-dev-qa-db-ja.com

すべてのプロパティのJavaScriptゲッター

端的に言えば、私はPHPスタイルのゲッターが必要な状況ですが、JavaScriptです。

私のJavaScriptはFirefoxでのみ実行されているので、Mozilla固有のJSで十分です。

JSゲッターを作成する唯一の方法は、その名前を指定することですが、all可能な名前のゲッターを定義したいと思います。これが可能かどうかはわかりませんが、知りたいです。

44
arantius

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で動作しません。すぐに。

61
B T

あなたが見つけることができる最も近いものは __ noSuchMethod __ であり、これはJavaScriptのPHPの__call()と同等です。

残念ながら、__ get/__ setに相当するものはありません。これは残念ですが、__ noSuchMethod__を実装できたのですが、__ noSuchMethod__を使用してプロパティを実装する方法(C#のように)はまだわかりません。

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

foo.bar(1, 2);
48
Ionuț G. Stan

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は両方をサポートします。

25
Ali

Javascript 1.5 には getter/setter構文糖度 があります。 John Resigによって非常によく説明されています here

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

5
Javier

機能する実装が本当に必要な場合は、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;
        }
    }
};
5
Vengarioth

私はニックネームの答えを使用して自分のソリューションを構築することになりました。私のソリューションは、すべてのプロパティに対して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;
                    };
                }
            })();
        }
    }
1
Kevin

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"
        };
    }
}
1
nickf

プロパティを取得または設定するだけでなく、メソッドをプロキシする方法を探していたので、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]);

誰かがそれをより一般的にする方法を知っていますか?渡すパラメーターの数をハードコーディングする必要なし(「元の」を変更せずに)

0
Enrique