web-dev-qa-db-ja.com

すべてのブラウザのObject.watch()?

Object.WatchObject.Observe は両方とも非推奨になりました(2018年6月現在)。


オブジェクトまたは変数の変更を監視する簡単な方法を探していましたが、IEではなくMozillaブラウザでサポートされているObject.watch()を見つけました。だから私は周りを探し始めて、誰かが何か同等のものを書いたかどうかを調べた。

私が見つけた唯一のものは a jQuery plugin ですが、それが最善の方法かどうかはわかりません。私はほとんどのプロジェクトでjQueryを使用しているので、jQueryの側面については心配していません...

とにかく、質問:そのjQueryプラグインの実際の例を見せてもらえますか?動作させるのに問題があります...

または、クロスブラウザで動作するより良い代替案を知っている人はいますか?

回答後に更新

回答ありがとうございます!ここに投稿されたコードを試しました: http://webreflection.blogspot.com/2009/01/internet-Explorer-object-watch.html

しかし、IEで動作させることはできなかったようです。以下のコードはFirefoxでは正常に動作しますが、IEでは何もしません。 Firefoxでは、watcher.statusが変更されるたびに、document.write()watcher.watch()が呼び出され、ページで出力を確認できます。 IEではそれは起こりませんが、最後のdocument.write()呼び出しが(IEとFFの両方で)正しい値を示すため、watcher.statusが値を更新していることがわかります。しかし、コールバック関数が呼び出されない場合、それは無意味です... :)

何か不足していますか?

var options = {'status': 'no status'},
watcher = createWatcher(options);

watcher.watch("status", function(prop, oldValue, newValue) {
  document.write("old: " + oldValue + ", new: " + newValue + "<br>");
  return newValue;
});

watcher.status = 'asdf';
watcher.status = '1234';

document.write(watcher.status + "<br>");
115
SeanW

(クロスポストは申し訳ありませんが、ここで同様の質問に答えたこの回答はここでうまくいきます)

少し前に、このために小さな object.watch shim を作成しました。 IE8、Safari、Chrome、Firefox、Operaなどで動作します。

113
Eli Grey

そのプラグインは単純にタイマー/インターバルを使用して、オブジェクトの変更を繰り返しチェックします。たぶん十分かもしれませんが、個人的にはオブザーバーとしてもっと身近になりたいです。

IEにwatch/unwatchを持ち込む試みは次のとおりです。 http://webreflection.blogspot.com/2009/01/internet-Explorer-object-watch.html =。

オブザーバーを追加するFirefoxの方法から構文を変更します。の代わりに :

var obj = {foo:'bar'};
obj.watch('foo', fooChanged);

あなたがやる:

var obj = {foo:'bar'};
var watcher = createWatcher(obj);
watcher.watch('foo', fooChanged);

甘くはありませんが、オブザーバーとしてすぐに通知されます。

19
Crescent Fresh

この質問に対する答えは少し時代遅れです。 Object.watchObject.observe はどちらも非推奨であり、使用すべきではありません。

現在、 Proxy オブジェクトを使用して、オブジェクトに加えられた変更を監視(および傍受)できるようになりました。基本的な例を次に示します。

var targetObj = {};
var targetProxy = new Proxy(targetObj, {
  set: function (target, key, value) {
      console.log(`${key} set to ${value}`);
      target[key] = value;
  }
});

targetProxy.hello_world = "test"; // console: 'hello_world set to test'

ネストされたオブジェクトに加えられた変更を観察する必要がある場合は、特殊なライブラリを使用する必要があります。私はObservable Slimを公開しましたが、これは次のように機能します:

var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
    console.log(JSON.stringify(changes));
});

p.testing.blah = 42; // console:  [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]
12
Elliot B.

現在の回答

新しい Proxy オブジェクトを使用します。これにより、ターゲットの変更を監視できます。

let validator = {
    set: function(obj, prop, value) {
        if (prop === 'age') {
            if (!Number.isInteger(value)) {
                throw new TypeError('The age is not an integer');
            }
            if (value > 200) {
                throw new RangeError('The age seems invalid');
            }
        }

        // The default behavior to store the value
        obj[prop] = value;

        // Indicate success
        return true;
    }
};

let person = new Proxy({}, validator);

person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception

2015年からの古い回答

ES7のObject.observe() を使用することもできます。 これはポリフィルです しかし Object.observe()は現在キャンセルされています 。ごめんなさい!

11
mikemaccana

Chrome 36以降では Object.observe も同様です。これは実際には将来のECMAScript標準の一部であり、MozillaのObject.watch

Object.observeはオブジェクトのプロパティでのみ機能しますが、Object.watch(これはデバッグ目的であり、実稼働環境での使用は意図されていません)。

var options = {};

Object.observe(options, function(changes) {
    console.log(changes);
});

options.foo = 'bar';
6
Husky

Object.defineProperty を使用できます。

barのプロパティfooを見る

Object.defineProperty(foo, "bar", {
  get: function (val){
      //some code to watch the getter function
  },

  set: function (val) {
      //some code to watch the setter function
  }
})
2

私のプロジェクトの1つで Watch.js を使用しました。このライブラリを使用する主な利点の1つは、次のとおりです。

「Watch.JSを使用すると、開発方法を変更する必要がありません。」

以下に例を示します

//defining our object however we like
var ex1 = {
        attr1: "initial value of attr1",
        attr2: "initial value of attr2"
};

//defining a 'watcher' for an attribute
watch(ex1, "attr1", function(){
        alert("attr1 changed!");
});

//when changing the attribute its watcher will be invoked
ex1.attr1 = "other value";
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/watch.min.js"></script>

これはこれと同じくらい簡単です!

1
NIKHIL C M