9

これを説明する方法はよくわかりませんが、コードを示して、達成したいことを説明します。

簡単なオブジェクトを作成するとします。

var test = {};

次に、プロパティを設定します:(構文を主張します。セッターとして関数を使用してはなりません)

test.hello = 'world';

とても簡単ですね 次に、新しいプロパティが設定されるたびに呼び出される関数をそのオブジェクトに追加したいと思います。このような:

var test = { 
                newPropertyHasBeenSet: function(name){ 
                    console.log(name + 'has been set.'); 
                } 
            };

test.hello = 'world';

// Now newPropertyHasBeenSet gets called with 'hello' as an argument.
// hello has been set.

それが可能かどうかはわかりませんが、それは非常に素晴らしいことです。誰もがそれを達成する方法のアイデアを持っていますか?

編集:プロパティgetについても同じことができるようにしたいと思います(たとえば、test.helloを呼び出します)。get('hello')

EDIT2:これはnode.jsを使用するサーバー側のJavaScript用です。

どうもありがとうございました、そして良い一日を!

4

5 に答える 5

8

この例をクロムで試してください(以前のコメントで述べたように、ES6 Proxyを使用しています):

var p = new Proxy(
    {},
    {
        get: function(obj, name) {
            console.log('read request to ' + name + ' property');
            if (name == 'test_test') return 1234;
            else return 'Meh';
        },
        set: function(obj, name, value) {
            console.log('write request to ' + name + ' property with ' + value + ' value');
        },
    }
);

console.log(p.test_test);
console.log(p.test);
p.qqq = 'test';

結果:

read request to test_test property
1234
read request to test property
Meh
write request to qqq property with test value
于 2012-07-19T01:18:30.107 に答える
2

既存のプロパティのtest.hello = "world"変更を検出する構文を維持することを本当に主張する場合は、次の EcmaScript 標準の一部になるまで数年待たなければなりません。Object.watch

幸いなことに、EcmaScript 5 でも を使用して同じことができますObject.definePropertyEli Gray は、Object.watch次のように呼び出すことができる素敵なポリフィルを作成しました。

var test = {};
test.watch("hello", function(propertyName, oldValue, newValue) {
    console.log(propertyName + " has been set to " + newValue);
});
test.hello = "world"; // triggers the watch handler

彼のコードを変更して、内部で別のハンドラーをトリガーするgetterこともできるため、プロパティ アクセスを検出できます。

残念ながら、ブラウザーのサポートは、Internet Explorer 9、Firefox 4、Chrome、Opera 12、Safari 5 などの最新のブラウザーに限定されています。

新しいプロパティが設定されたときにハンドラーをトリガーしたい場合は、さらに問題が発生します。あなたができる最善の方法は、オブジェクトをプロキシset内にラップし、トラップを配置することです。this.getOwnPropertyDescriptor(name)次に、「真実」の値を返すかどうかをテストすることで、プロパティが既に存在するかどうかを検出できます。ただし、Proxy API は非常に実験的なものであり、試用できるプロトタイプの実装を提供するブラウザはごくわずかです。適切なブラウザー サポートを備えた完全な API を取得するには、おそらくかなりの時間を待たなければならないでしょう。

于 2012-07-19T00:19:20.640 に答える
2
var test = {};

Object.defineProperty(test, "hello", {
    get : function () {
        return this._hello;
    },
    set : function (val) {
        alert(val);
        this._hello = val;
    }
});

test.hello = "world";

そんな感じ。ただし、古いブラウザでは動作しません。

ここでその他のオプションを見つけることができます: http://robertnyman.com/javascript/javascript-getters-setter.html

于 2012-07-19T00:17:04.547 に答える
0

キー値の監視とバインディングを提供するライブラリが必要です。

ember-metal はそのようなライブラリの 1 つです。

基本的にオブジェクトを作成し、それらのオブジェクトのプロパティにオブザーバーを登録できます。

var obj = Em.Object.create({
   val: null
   valDidChange:function(){...}.observes('val')
});

valDidChange はval、プロパティが変更されるたびに発生するため、

obj.set('val', 'newValue');

オブザーバーが発砲します。

于 2012-07-18T23:58:05.293 に答える
0

このようなものはどうですか?これがjsfiddleです。

var objectManager = function(obj, setCallback){
    this.obj = obj;
    this.setCallback = setCallback;
};

objectManager.prototype.setProperty = function(prop, value){
    this.obj[prop] = value;
    this.setCallback(prop);
};

objectManager.prototype.getObj = function(){
    return this.obj;
};

// USAGE:
var testMgr = new objectManager({}, function(prop){
    console.log(name + ' has been set.'); 
});
testMgr.setProperty("hello", "world"); //should log "hello has been set.";
于 2012-07-18T23:59:37.040 に答える