Object.watch () untuk semua browser?


118

Harap diperhatikan bahwa Object.Watchdan Object.Observekeduanya sudah tidak digunakan lagi sekarang (mulai Jun 2018).


Saya sedang mencari cara mudah untuk memonitor objek atau variabel untuk perubahan, dan saya menemukan Object.watch(), itu didukung di browser Mozilla, tetapi tidak di IE. Jadi saya mulai mencari di sekitar untuk melihat apakah ada yang telah menulis semacam padanan.

Tentang satu-satunya hal yang saya temukan adalah plugin jQuery , tetapi saya tidak yakin apakah itu cara terbaik untuk melakukannya. Saya pasti menggunakan jQuery di sebagian besar proyek saya, jadi saya tidak khawatir tentang aspek jQuery ...

Bagaimanapun, pertanyaannya: Bisakah seseorang menunjukkan kepada saya contoh kerja plugin jQuery itu? Saya mengalami masalah dalam membuatnya bekerja ...

Atau, apakah ada yang tahu tentang alternatif yang lebih baik yang akan bekerja lintas browser?

Perbarui setelah jawaban :

Terima kasih semuanya atas tanggapannya! Saya mencoba kode yang diposting di sini: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html

Tapi sepertinya saya tidak bisa membuatnya bekerja dengan IE. Kode di bawah berfungsi dengan baik di Firefox, tetapi tidak melakukan apa pun di IE. Di Firefox, setiap kali watcher.statusdiubah, document.write()in watcher.watch()dipanggil dan Anda dapat melihat hasilnya di halaman. Di IE, itu tidak terjadi, tetapi saya dapat melihat itu watcher.statusmemperbarui nilai, karena document.write()panggilan terakhir menunjukkan nilai yang benar (di IE dan FF). Tapi, jika fungsi callback tidak dipanggil, maka itu tidak ada gunanya ... :)

Apakah saya melewatkan sesuatu?

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>");

2
IIRC Anda dapat menggunakan onPropertyChange di IE
scunliffe

1
Gantikan document.write () dengan alert (). Seharusnya itu berjalan baik baik saja.
Ionuț G. Stan

Jawaban:


113

(Maaf untuk posting silang, tapi jawaban yang saya berikan untuk pertanyaan serupa ini berfungsi dengan baik di sini)

Saya telah membuat objek kecil. Perhatikan shim untuk ini beberapa waktu yang lalu. Ini berfungsi di IE8, Safari, Chrome, Firefox, Opera, dll.


10
Penjelasan tentang cara menggunakannya dan cara kerjanya secara internal akan menyenangkan bagi kita yang bukan master JS, terima kasih.
maraujop


jsfiddle.net/kSWxP PETUNJUK: gunakan Firefox (pernyataan terakhir tidak dicetak di Chrome)
Mars Robertson


Saya tahu ide itu Object.defineProperty()ada. Saya akhirnya melihat referensi MDN untuk melihat cara kerjanya.
jumpnett

19

Plugin itu hanya menggunakan timer / interval untuk berulang kali memeriksa perubahan pada suatu objek. Mungkin cukup baik tetapi secara pribadi saya ingin lebih cepat sebagai pengamat.

Berikut ini upaya untuk membawa watch/ unwatchke IE: http://webreflection.blogspot.com/2009/01/internet-explorer-object-watch.html .

Itu mengubah sintaks dari cara Firefox menambahkan pengamat. Dari pada :

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

Anda melakukan:

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

Tidak semanis itu, tetapi sebagai pengamat Anda akan segera diberi tahu.


Ya, perhatikan stempel waktu itu ... tidak perlu downvote, juga crescentfresh menambahkan lebih banyak info ke posting, meskipun itu adalah tautan yang sama. Sementara itu, saya sudah mencoba kode yang ditemukan di halaman itu dan masih melihat masalah. Saya mungkin mengabaikan sesuatu. Saya telah memperbarui posting asli saya dengan info lebih lanjut ...
SeanW

13

Jawaban atas pertanyaan ini agak ketinggalan jaman. Object.watch dan Object.observe keduanya tidak digunakan lagi dan sebaiknya tidak digunakan.

Hari ini, Anda sekarang dapat menggunakan objek Proxy untuk memantau (dan mencegat) perubahan yang dibuat pada suatu objek. Inilah contoh dasarnya:

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'

Jika Anda perlu mengamati perubahan yang dibuat pada objek bersarang, Anda perlu menggunakan pustaka khusus. Saya menerbitkan Observable Slim dan berfungsi seperti ini:

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

Jawaban Saat Ini

Gunakan objek Proxy baru , yang dapat melihat perubahan pada targetnya.

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

Jawaban lama dari 2015

Anda bisa menggunakan Object.observe () dari ES7 . Ini polyfill. Tapi Object.observe () sekarang dibatalkan . Maaf orang!


Hm, saya tidak bisa membuat polyfill ini berfungsi di ios safari. Saya mendapatkan Error: undefined is not a function (mengevaluasi 'Object.observe (a.imgTouch, function (a) {console.debug ("lastX:" + a)})')
infomofo

@infomofo Hai, Anda ingin membuka masalah pada halaman proyek, dengan semua detail yang dapat Anda berikan? Saya belum mengujinya di iOS, tetapi saya akan menyelidiki masalahnya.
MaxArt

6

Perhatikan bahwa di Chrome 36 dan yang lebih tinggi, Anda juga dapat menggunakannya Object.observe. Ini sebenarnya adalah bagian dari standar ECMAScript masa depan, dan bukan fitur khusus browser seperti milik Mozilla Object.watch.

Object.observehanya bekerja pada properti objek, tetapi performanya jauh lebih baik daripada Object.watch(yang dimaksudkan untuk tujuan debugging, bukan penggunaan produksi).

var options = {};

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

options.foo = 'bar';

1
Seperti pada 2018, ini tidak digunakan lagi dan tidak lagi didukung oleh semua browser utama
Sergei Panfilov

4

Anda dapat menggunakan Object.defineProperty .

awasi properti bardifoo

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

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

Ini bagus! Tapi saya akan memodifikasinya sedikit :) Agar tidak menimpa setter asli. Saya akan melakukan referensi foo._someObject = foo.someObject
calmbird

sederhana dan
elegan

1

Saya telah menggunakan Watch.js di salah satu proyek saya. Dan itu berfungsi dengan baik. Salah satu keuntungan utama menggunakan perpustakaan ini adalah:

"Dengan Watch.JS Anda tidak perlu mengubah cara Anda berkembang."

Contoh diberikan di bawah ini

//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/melanke-watchjs@1.5.0/src/watch.min.js"></script>

Ini sesederhana ini!


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.