對象咱們都知道是什麼,可是對象當咱們想對對象作些限制,該怎麼辦呢,能夠用對象的內置屬性
vue
Object.defineProperty()
複製代碼
mdn上是這麼定義的: Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性,bash
語法
obj.defineProperty(obj,prop,descriptor)函數
參數
1.obj:要執行操做的對象 2.prop:操做的對象須要定義或修改的屬性的名稱 3.descriptor:具體的操做內容 return
傳遞給函數的對象。ui
是否能夠刪除或者修改目標對象屬性的特性(就是咱們如今要說的這幾個) 默認值爲false,設置爲true的時候能夠被修改或刪除, 一旦被設置爲false,就不能再把它變爲可配置的,這一點很重要this
舉個栗子
spa
當首先設置爲true的時候能夠被刪除code
var obj = {
name:'clearlove'
}
Object.defineProperty(obj,'name',{
configurable:true
})
//刪除屬性
delete obj.name
console.log(obj.name) //undefined
複製代碼
設置爲false的時候不能夠被刪除cdn
var obj = {
name:'clearlove'
}
Object.defineProperty(obj,'name',{
configurable:false
})
//刪除屬性
delete obj.name
console.log(obj.name) //clearlove
複製代碼
當設置爲true的時候能夠被修改特性對象
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable: false,
enumerable: true,
configurable: true
});
//從新修改特性
Object.defineProperty(obj, "name", {
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.name); //clearlove
複製代碼
當設置爲false的時候不能夠修改特性blog
var obj = {
name: 'clearlove'
}
//從新修改特性
//從新修改特性
Object.defineProperty(obj, "name", {
writable: false,
enumerable: false,
configurable: false
});
Object.defineProperty(obj, "name", {
writable: true,
enumerable: true,
configurable: false
});
console.log(obj.name);
複製代碼
是否能夠被再次枚舉(使用for...in或Object.keys())默認爲fasle,設置爲true能夠被枚舉;設置爲false,不能被枚舉
舉個栗子
var obj = {}
// 第一種狀況:enumerable設置爲false,不能被枚舉。
Object.defineProperty(obj, "newKey", {
value: "hello",
writable: false,
enumerable: false
});
// 枚舉對象的屬性
for( var attr in obj ){
console.log( attr ); // undefined
}
// 第二種狀況:enumerable設置爲true,能夠被枚舉。
Object.defineProperty(obj, "newKey", {
value: "hello",
writable: false,
enumerable: true
});
// 枚舉對象的屬性
for( var attr in obj ){
console.log( attr ); //newKey
}
複製代碼
對應屬性的值
var obj = {
name: 'clearlove'
}
//從新修改特性
//從新修改特性
Object.defineProperty(obj, "name", {
value:'Meiko'
});
console.log(obj.name); //Meiko
複製代碼
屬性值是否能夠被修改,默認爲false
設置爲false,不能被修改
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable:false
});
//修改name的值
obj.name = 'Meiko'
console.log(obj.name); //clearlove
複製代碼
設置爲true能夠被修改
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable:true
});
//修改name的值
obj.name = 'Meiko'
console.log(obj.name); //Meiko
複製代碼
在使用Object.defineProperty時,三個屬性默認都爲fasle,當不使用時默認都是爲true
重點來講說get和set
在屬性值被獲取的時候進行的操做
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj,'name',{
//在屬性被讀取時,執行的操做
get:function(){
console.log('我被讀取了')
//return value
}
})
console.log(obj.name) //我被讀取了
複製代碼
在屬性設置時進行的操做
//在非嚴格模式下只設置set會打印undefined
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj,'name',{
//在屬性被讀取時,執行的操做
set:function(){
console.log('我被修改了')
return value
}
})
obj.name = 'Meiko'
console.log(obj.name)
複製代碼
基於上述特性咱們是否能夠作一個相似vue計算屬性的東西呢
舉個栗子
//根據年齡計算出生日期
//1.獲取如今的年份
var myDate = new Date();
var tYear = myDate.getFullYear();
//2.新建對象賦予年份
var obj = {
nowyear:tYear,
_oldyear:22,
birthdyear:0
}
//3.輸入年齡計算,根據年齡出生年
Object.defineProperty(obj,'oldyear',{
get:function(){
return this._oldyear
},
set:function(newValue){
this._oldyear = newValue
this.birthdyear = this.nowyear - newValue
}
})
//設置oldyear的值,獲得出生年
obj.oldyear = 25
console.log(obj.birthdyear)//1994
複製代碼