[Object][进阶]Object.defineProperty(),Object.defineProperties(),Object.getOwnPropertyDescriptor()
vue源码学习双向数据绑定原理前置知识
Object.defineProperty()
Object.defineProperty(obj,prop,descriptor)
接收三个参数:属性所在的对象、属性的名字、描述符对象
1.数据属性
描述符对象必须是:configurable、enumerable、writable、value
使用Object.defineProperty()方法定义的数据属性,configurable、enumerable、writable默认为false
var book = {}
Object.defineProperty(book, 'name', {
value: 'dange'
})
Object.getOwnPropertyDescriptor(book, 'name').value //"dange"
Object.getOwnPropertyDescriptor(book, 'name').configurable //false
Object.getOwnPropertyDescriptor(book, 'name').writable //false
Object.getOwnPropertyDescriptor(book, 'name').enumerable//false
使用{}或者点方法定义的数据属性,configurable、enumerable、writable默认为true
var book = { name:'dange'}
Object.getOwnPropertyDescriptor(book,'name').value //"dange"
Object.getOwnPropertyDescriptor(book,'name').configurable //true
Object.getOwnPropertyDescriptor(book,'name').writable //true
Object.getOwnPropertyDescriptor(book,'name').enumerable//true
2.访问器属性
描述符对象必须是:configurable、enumerable、get、set
var book = {
_year: 2020,
edition: 1
};
Object.defineProperty(book, 'year', {
get: function() {
return this._year;
},
set: function(newVal) {
if(newVal > 2020) {
this._year = newVal;
this.edition += newVal - 2020;
}
}
})
book.year = 2021; //此时调用set
console.log(book.edition);
访问器属性:设置一个属性的值会导致其他属性发生变化
Object.defineProperties()
定义多个属性
Object.defineProperties(obj, props)
接收两个对象参数:要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对应
var book = {};
Object.defineProperty(book, {
_year: 2020,
edition: 1
year: {
get: function() {
return this._year;
},
set: function(newVal) {
if(newVal > 2020) {
this._year = newVal;
this.edition += newVal - 2020;
}
}
}
})
Object.getOwnPropertyDescriptor()
该方法可以去个给定属性的描述符
Object.getOwnPropertyDescriptor(obj, prop)
接收两个参数:属性所在的对象、要读取其描述符的属性名称
返回值是一个对象, 如果是数据属性,这个对象的属性有:configurable、enumerable、writable、value;如果对象是访问器属性,这个对象的属性有:configurable、enumerable、get、set
var book = {
name: 'dange',
_year: 2020,
edition: 1
};
Object.defineProperty(book, 'year', {
get: function() {
return this._year;
},
set: function(newVal) {
if(newVal > 2020) {
this._year = newVal;
this.edition += newVal - 2020;
}
}
})
Object.getOwnPropertyDescriptor(book, 'name').value //"dange"
Object.getOwnPropertyDescriptor(book, 'name').configurable //true
Object.getOwnPropertyDescriptor(book, 'name').writable //true
Object.getOwnPropertyDescriptor(book, 'name').enumerable //true
Object.getOwnPropertyDescriptor(book, 'name').get() //Uncaught TypeError: Object.getOwnPropertyDescriptor(...).get is not a function
Object.getOwnPropertyDescriptor(book, 'name').set() //Uncaught TypeError: Object.getOwnPropertyDescriptor(...).set is not a function
typeof Object.getOwnPropertyDescriptor(book, 'name').get //"undefined"
Object.getOwnPropertyDescriptor(book, 'year').value //undefined
typeof Object.getOwnPropertyDescriptor(book, 'year').get //"function"
坚持,坚持,坚持。再坚持坚持!