2014-11-06 5 views
1

Object.observe() 콜백의 변경 배열은 다음과 같은 네 가지 속성을 가진 개체를 포함Object.observe()가 콜백에 대한 변경 데이터 경로를 제공하지 않는 이유는 무엇입니까?

왜 ISN ' 거기에기본적으로 제공되는? 예 : 만약 아니, 당신은 방법을 설명하시기 바랍니다 수 (observed.js,
는하지만 기본 observe()의 성능 향상이 손실됩니다 걱정 :

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" 

Object.observe()를 확장하는 Node.js를 모듈은 또한 경로가 포함 할 것 그것은 그때 구현됩니까?). 모듈 browserify이 될 수도 있지만 동기식 환경에서 성능이 뛰어나다 고 상상할 수는 없으며 왜 아무도 추가 path 속성에 대해 생각한 것 같습니다.

답변

6

명확한 경로가 없으므로

는 다음과 같은 고려 :

var movall = {moo: "bar", val: 5}; 
var ob1 = {a: mooval}; 
var ob2 = {b: movall}; 

지금의 내가 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 
    } 
} 

(참고 : 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" 

위의 코드하지 자신의 위험에 생산 품질, 사용.

+0

좋은 지적이지만, 당신이 묘사 한 정확한 상황에서'Object.observe()'는 어떻게 행동합니까? 두 개의 다른 객체가 첫 번째 객체를 포함하면 3 개의 이벤트가 변경됩니까? 새 객체가 콜백에 전달되므로 상속/객체 중첩이 문제가되지 않습니다. BTW :'path'는'movall','ob' 또는'ob2'를 포함해서는 안되며, 뒤에 오는 것만 포함해야합니다. 전달 된 객체와 결합하여'type'과'oldValue'를 변경하면 직접 OT 연산을 생성 할 수 있습니다. – CoDEmanX

+0

변경 이벤트는 숲에 떨어지는 나무처럼 관찰 된 경우에만 발생합니다. 그래서 우리가'ob2'를 관찰한다면, 네, 또 다른 변화 이벤트가 그 관찰자에게 보내질 것입니다. –

+0

명확히하기 위해서 : 우리가'movall'과'ob2'를 관찰한다면,'ob2'는'movall'을 포함하고,'ob2' -'ob2.b.movall.moo = "foo"'를 변경합니다 'movall'과 'ob2'에 하나의 변경 이벤트가 있습니까? 그렇다면 중첩 된 객체 ('movall'의 경우 'moo'및 'ob2'의 경우 'b.movall.moo')와 상관없이 우리가 관찰하는 객체와 관련하여 경로 모호성이 없습니다. – CoDEmanX