defineProperty //就是定義一個新屬性或者修改一個已存在的屬性
Object.defineProperty(obj, prop, desc)
obj 需要定義屬性的當前對象
prop 當前需要定義的屬性名
desc 屬性描述符
var Person = {}
Object.defineProperty(Person, 'name', {
value: 'jack',
writable: true // 是否可以改變
})
console.log(Person)
configurable
當且僅當該屬性的 configurable 爲 true 時,該屬性描述符
才能夠被改變,同時該屬性也能從對應的對象上被刪除。默認爲 false。
enumerable
當且僅當該屬性的enumerable
爲true
時,該屬性才能夠出現在對象的枚舉屬性中。默認爲 false。
數據描述符同時具有以下可選鍵值:
value
該屬性對應的值。可以是任何有效的 JavaScript 值(數值,對象,函數等)。默認爲 undefined
。
writable
當且僅當該屬性的writable
爲true
時,value
才能被賦值運算符改變。默認爲 false。
存取描述符同時具有以下可選鍵值:
get
一個給屬性提供 getter 的方法,如果沒有 getter 則爲 undefined
。當訪問該屬性時,該方法會被執行,方法執行時沒有參數傳入,但是會傳入this
對象(由於繼承關係,這裏的this
並不一定是定義該屬性的對象)。
默認爲 undefined
。
set
一個給屬性提供 setter 的方法,如果沒有 setter 則爲 undefined
。當屬性值修改時,觸發執行該方法。該方法將接受唯一參數,即該屬性新的參數值。
默認爲 undefined
。
var data = {name: 'kindeng'};
observe(data);
data.name = 'dmq'; // 哈哈哈,監聽到值變化了 kindeng --> dmq
function observe(data) {
if (!data || typeof data !== 'object') {
return;
}
// 取出所有屬性遍歷
Object.keys(data).forEach(function(key) {
defineReactive(data, key, data[key]);
});
};
function defineReactive(data, key, val) {
observe(val); // 監聽子屬性
Object.defineProperty(data, key, {
enumerable: true, // 可枚舉
configurable: false, // 不能再define
get: function() {
return val;
},
set: function(newVal) { // set 監聽屬性值的修改
console.log('哈哈哈,監聽到值變化了 ', val, ' --> ', newVal);
val = newVal;
}
});
}