Object.defineProperty()方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性(屬性為響應(yīng)式屬性),并返回此對(duì)象。
語(yǔ)法:
Object.defineProperty(obj, prop, descriptor)
obj要定義屬性的對(duì)象。
prop要定義或修改的屬性的名稱或 descriptor要定義或修改的屬性描述符。
get:
屬性的 getter 函數(shù),如果沒(méi)有 getter,則為 undefined。當(dāng)訪問(wèn)該屬性時(shí),會(huì)調(diào)用此函數(shù)。執(zhí)行時(shí)不傳入任何參數(shù),但是會(huì)傳入 this 對(duì)象(由于繼承關(guān)系,這里的this并不一定是定義該屬性的對(duì)象)。該函數(shù)的返回值會(huì)被用作屬性的值。
默認(rèn)為 undefined。
set:
屬性的 setter 函數(shù),如果沒(méi)有 setter,則為 undefined。當(dāng)屬性值被修改時(shí),會(huì)調(diào)用此函數(shù)。該方法接受一個(gè)參數(shù)(也就是被賦予的新值),會(huì)傳入賦值時(shí)的 this 對(duì)象。
默認(rèn)為 undefined。
Object.defineProperty(person,'age',{
四個(gè)配置項(xiàng):value enumerable writable configurable
// value:18, //給屬性添加值
// enumerable:true, //控制屬性是否可以枚舉,默認(rèn)值是false
// writable:true, //控制屬性是否可以被修改,默認(rèn)值是false
// configurable:true //控制屬性是否可以被刪除,默認(rèn)值是false
兩個(gè)函數(shù)配置項(xiàng):get() set()
//當(dāng)有人讀取person的age屬性時(shí),get函數(shù)(getter)就會(huì)被調(diào)用,且返回值就是age的值
get(){
console.log('有人讀取age屬性了')
return number //更改number的值即時(shí)賦值給age
},
//當(dāng)有人修改person的age屬性時(shí),set函數(shù)(setter)就會(huì)被調(diào)用,且會(huì)收到修改的具體值
set(value){
console.log('有人修改了age屬性,且值是',value)
number = value //同上
}
})
使用Object.defineProperty實(shí)現(xiàn)雙向數(shù)據(jù)綁定
var model = {};
Object.defineProperty(model,'txt',{
get:function(){},
set:function(val){
var span = document.getElementsByTagName('span')[0];
span.innerHTML = val;
}
})
var input = document.getElementsByTagName('input')[0];
input.oninput = function(){
model.txt = input.value;//必然觸發(fā)set函數(shù)
}
當(dāng)我們使用 Object.defineProperty 對(duì)數(shù)組對(duì)象賦值有一個(gè)新對(duì)象的時(shí)候,會(huì)執(zhí)行set方法
同時(shí) 在雙向數(shù)據(jù)綁定的過(guò)程中 也運(yùn)用到了數(shù)據(jù)劫持的概念
數(shù)據(jù)劫持 在使用或者設(shè)置某的對(duì)象的屬性的時(shí)候,通過(guò)一系列的代碼攔截此次的此次的行為。即可以在賦值過(guò)程中添加一些操作或者修改返回的結(jié)果。
給數(shù)據(jù)添加監(jiān)聽(tīng),一旦數(shù)據(jù)發(fā)生變化,就執(zhí)行視圖的修改操作,這個(gè)過(guò)程就是數(shù)據(jù)劫持。