如何订阅对象变化?
如何订阅对象变化?
我想知道如何订阅JavaScript对象的更改,就像Redux一样。我已经阅读了很多JS文档,但是我找不到一个非过时的方法来处理这个问题(Object.protype.watch()
和Object.observe()
已经被弃用)。此外,我阅读了一些关于这个主题的Stackoverflow问题,但它们都至少有5年的历史了。为了说明我的问题,我将举一个例子。\n这是我想要监视的一个对象:\n
const store = { anArray = [ 'Hi', 'my', 'name', 'is' ] }
\n.. 这是一个改变store
对象的函数:\n
function addAName() { store.anArray.push('Bob') }
\n我在这个例子中的目标是每当store
对象发生变化时触发以下函数:\n
function storeChanged() { console.log('The store object has changed!') }
\n提前谢谢!
如何订阅对象的更改?
当我们需要在对象发生更改时进行一些处理时,我们可以使用Object.defineproperty()来创建响应式的getter和setter。它具有良好的浏览器支持,并且非常方便。
下面是一个示例代码,演示了如何使用Object.defineproperty()来订阅对象的更改:
function Store() { let array = []; Object.defineProperty(this, 'array', { get: function() { console.log('Get:', array); return array; }, set: function(value) { array = value; console.log('Set:', array) } }); } var store = new Store(); store.array; // Get: [] store.array = [11]; // Set: [11] store.array.push(5) // Set: [11, 5] store.array = store.array.concat(1, 2, 3) // Set: [11, 5, 1, 2, 3]
在这个例子中,我们创建了一个名为Store的对象。在Store对象中,我们定义了一个名为array的属性,并使用Object.defineProperty()来定义其getter和setter方法。当我们访问store.array时,getter方法会被调用,并打印出当前的array值。当我们对store.array进行赋值时,setter方法会被调用,并打印出新的array值。
通过使用Object.defineproperty()来创建响应式的getter和setter,我们可以轻松地订阅对象的更改,并在更改发生时执行一些逻辑。这对于构建具有实时数据更新的应用程序非常有用。
如何订阅对象的更改?
问题的出现原因是为了解决在使用对象时不需要任何间接方式的问题,可以使用代理。
通过将所有对象包装在observable中,您可以自由编辑您的存储,并且_base会跟踪哪个属性已更改。
代码如下:
const observable = (target, callback, _base = []) => { for (const key in target) { if (typeof target[key] === 'object') target[key] = observable(target[key], callback, [..._base, key]) } return new Proxy(target, { set(target, key, value) { if (typeof value === 'object') value = observable(value, callback, [..._base, key]) callback([..._base, key], target[key] = value) return value } }) } const a = observable({ a: [1, 2, 3], b: { c: { d: 1 } } }, (key, val) => { console.log(key, val); }) a.a.push(1) a.b.c.d = 1 a.b = {} a.b.c = 1
这可能是一种很好的解决方法,但请注意:如果您正在观察数组的length属性的更改,它不会捕获直接索引添加,例如a.a[10] = true。
如何订阅对象的变化?
在ECMA6中,你尝试过使用Proxy吗?我认为这就是你要找的东西。
你只需要定义一个函数作为Proxy的验证器的set方法,就像这样:
let validator = { set: function(target, key, value) { console.log(`The property ${key} has been updated with ${value}`); return true; } }; let store = new Proxy({}, validator); store.a = 'hello'; // console => The property a has been updated with hello
这个答案对我帮助很大!我基于这个原理创建了一个类似于flux的存储。非常酷!我现在正在考虑的唯一一件事是,使用普通的类并在那里使用set和get属性。通过这种方法,你需要指定所有变量并变得有点冗余,但另一方面,你可以控制这个对象控制的值的类型。使用代理方法,通过查看文件,你无法了解存储在其中的所有内容。