CoD*_*anX 1 javascript observers ecmascript-harmony object.observe
Object.observe()回调的changes数组包含具有以下四个属性的对象:
为什么没有path本地提供的?例:
var ob = {
foo: [
{moo: "bar", val: 5},
{val: 8}
]
}
ob.foo[0].val = 1;
// callback should provide path "foo.0.val" or "foo[0].val"
Run Code Online (Sandbox Code Playgroud)
有一个Node.js模块扩展Object.observe()到也包括路径:observed.js,
但我担心本机的性能提升observe()会丢失(如果没有,请你解释它是如何实现的?).这也许可以browserify模块,但无法想象它会在同步环境表现良好,我仍然不知道为什么没有人似乎已经想到了一个额外的path属性.
小智 6
因为没有明确的路径.
考虑以下:
var movall = {moo: "bar", val: 5};
var ob1 = {a: mooval};
var ob2 = {b: movall};
Run Code Online (Sandbox Code Playgroud)
现在让我说我观察movall.然后我更新moo.路径是什么?是movall.moo,或ob1.a.moo,或ob2.b.moo?如果我观察到ob1,则没有报告任何变化,因为它的任何属性都没有变化(变化是其中一个属性的内部变量,不计算在内).
对象独立于嵌套在其他对象中的存在.它们可以嵌套在多个其他对象中.没有唯一的"路径"描述如何从可能的多个起点到可能已更改的特定属性.
JS也不知道您到达要更改的财产的路径.因此ob.foo[0].val = 1;,JS只是评估链,到达foo[0]对象,更改其val属性,并且在那时不知道它是如何发生的foo[0].它只知道foo[0]已经改变了.它在内部发生了变化ob,但也可能在其他碰巧具有foo[0]属性的对象中发生了变化.
但是,您可以通过在低级观察/通知机制之上构建一些机器来实现您似乎尝试的目标.我们将在一个对象上定义一个函数,该函数在其属性对象上设置观察者,依此递归,并使用正确构造的路径传播更改记录:
function notifySubobjectChanges(object) {
var notifier = Object.getNotifier(object); // get notifier for this object
for (var k in object) { // loop over its properties
var prop = object[k]; // get property value
if (!prop || typeof prop !== 'object') break; // skip over non-objects
Object.observe(prop, function(changes) { // observe the property value
changes.forEach(function(change) { // and for each change
notifier.notify({ // notify parent object
object: change.object, // with a modified changerec
name: change.name, // which is basically the same
type: change.type,
oldValue: change.oldValue,
path: k +
(change.path ? '.' + change.path : '') // but has an addt'l path property
});
});
});
notifySubobjectChanges(prop); // repeat for sub-subproperties
}
}
Run Code Online (Sandbox Code Playgroud)
(注意:change对象被冻结,我们无法添加任何内容,因此我们必须复制它.)
现在
a = { a: { b: {c: 1 } } }; // nested objects
notifySubobjectChanges(a); // set up recursive observers
Object.observe(a, console.log.bind(console)); // log changes to console
a.a.b.c = 99;
>> 0: Object
name: "c"
object: Object
oldValue: 1
path: "a.b" // <=== here is your path!
type: "update"
Run Code Online (Sandbox Code Playgroud)
以上代码不是生产质量,使用风险自负.
| 归档时间: |
|
| 查看次数: |
1291 次 |
| 最近记录: |