2012-03-24 8 views
3

내가 원하는 것은 get/set에 대한 동작을 수정하기 위해 JavaScript 속성을 래핑하는 기능입니다. 값이있는 속성에 대한Object.create를 사용하여 만든 JavaScript 속성의 가져 오기/설정 메서드에 액세스

, 나는 다음을 수행 할 수 있습니다

var obj = { 
    myProperty : 0 
}; 

function notifyOfChange(obj, propertyName) { 
    var propertyValue = obj[propertyName]; 
    Object.defineProperty(obj, propertyName, { 
     get : function() { return propertyValue; }, 
     set : function(newValue) { 
      var propertyValue = newValue; 
      console.log("Message from notifyOfChange."); 
     } 
    }); 
}; 

obj.myProperty = 10; // outputs "Message from notifyOfChange." 

그러나, 무엇 myProperty 이미 게터/세터가 있는지?

var obj = Object.create({}, { 
    myProperty : { 
     get : function() { return this._myProperty; }, 
     set : function(value) { 
      console.log("Message from obj itself."); 
      this._myProperty = value; 
     }, 
     configurable : true 
    } 
}); 

obj.myProperty = 10; // outputs "Message from obj itself"; 

notifyOfChange(obj, "myProperty"); 

obj.myProperty = 10; // outputs "Message from notifyOfChange." 

내가 notifyOfChange에서 호출 할 수 있도록 myProperty 익명 세터를 감지 할 수있는 방법이 있습니까?

참고 : 모든 객체에서 notifyOfChange를 사용하고 싶습니다. myProperty setter의 명명 된 함수를 사용하는 것이 효과적이지 않습니다.

답변

5
function notifyOfPropertyChange(obj, propertyName) { 

    var desc = Object.getOwnPropertyDescriptor(obj, propertyName); 

    if ("value" in desc && desc.writable) { 
     // Value property 

     var propertyValue = obj[propertyName]; 

     Object.defineProperty(obj, propertyName, { 
      get: function() { return propertyValue; }, 
      set: function (newValue) { 
       propertyValue = newValue; 
       console.log("Message from notifyOfChange."); 
      }, 
      configurable: true, 
      enumerable: desc.enumerable 
     }); 

    } else if (desc.set) { 
     // Getter/setter property 

     // Redefine the setter, keep the getter if it exists 
     var originalSet = desc.set.bind(obj); 
     desc.set = function (newValue) { 
      originalSet(newValue); 
      console.log("Message from notifyOfChange."); 
     }; 
     Object.defineProperty(obj, propertyName, desc); 
    } 
} 

Object.getOwnPropertyNames을 사용하면 수정할 속성 이름의 전체 목록을 가져올 수 있습니다.

Object.getOwnPropertyDescriptor에 대한 설명은 MDN을 참조하십시오.

+0

좋은데 왜 if-condition에서'desc.writable'을 사용합니까? – Bergi

+1

쓰기가 가능한 속성이 아닌 경우에는 설정자에게 쓰기 기능을 부여하고 싶지는 않을 것입니다. – kpozin

+0

좋아, 내가 오류를 던지기 전에 "통지"메시지를 기록했을 :-) – Bergi