使用Object.defineProperty為對(duì)象定義屬性
引言
Object.defineProperty,顧名思義,為對(duì)象定義屬性,但是疑問(wèn)是,我們有太多的辦法去定義一個(gè)對(duì)象的屬性了,比如foo['bar'] = 100,比如foo.bar = 100,為什么還要用它?會(huì)不會(huì)是自找麻煩呢?
使用Object.defineProperty的原因很簡(jiǎn)單,因?yàn)橹挥型ㄟ^(guò)它才能定義一些值得特殊屬性,比如是否可寫,是否可枚舉,接下來(lái)我們用例子來(lái)看一下。
定義或修改屬性
var demo = {
foo:1,
bar:2
};
Object.defineProperty(demo, 'foo',{
value:100
});
Object.defineProperty(demo, 'foobar',{
value:"hello"
});這個(gè)例子中,第一個(gè)修改了demo的屬性foo,第二個(gè)創(chuàng)建了foobar屬性,屬性的值是第三個(gè)參數(shù)中value。第一個(gè)參數(shù)是要修改的對(duì)象,第二個(gè)參數(shù)是屬性名,第三個(gè)參數(shù)是“描述”,一個(gè)可以對(duì)屬性進(jìn)行一些設(shè)定的鍵值對(duì)。
所以,如果你想讓一個(gè)屬性變得不可枚舉,要這么寫
Object.defineProperty(demo, 'foobar',{
value:"hello",
enumerable:false
});可枚舉的屬性
上一個(gè)例子其實(shí)是沒(méi)有意義的,因?yàn)?code>enumerable的默認(rèn)值就是false,用上述方法創(chuàng)建的屬性默認(rèn)就是不可枚舉,那么什么是不可枚舉呢?很簡(jiǎn)單,for...in 或 Object.keys找不到它,用MDN上的栗子
var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable:true });
Object.defineProperty(o, "b", { value : 2, enumerable:false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
o.d = 4; // 如果使用直接賦值的方式創(chuàng)建對(duì)象的屬性,則這個(gè)屬性的enumerable為true
for (var i in o) {
console.log(i);
}
// 打印 'a' 和 'd' (in undefined order)
Object.keys(o); // ["a", "d"]
o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false所以,同樣你可以定義的屬性包括
Writable 是否可寫
Configurable 是否能刪除
所以,Object.defineProperty相當(dāng)于 .和[]的一個(gè)加強(qiáng)版,但是另外一個(gè)因素也讓他變得更強(qiáng)大。
屬性的getter和setter
通過(guò)Object.defineProperty可以自定義屬性的getter和setter,看栗子
var demo = {
foobar: 'hello'
}
var v;
Object.defineProperty(demo,'foobar',{
get:function(){
console.log('i am been getting')
return v + '?'
},
set:function(e){
v = e + '!';
console.log('i am changing!')
}
}
)
demo.foobar = "bye"
console.dir(demo.foobar)
//'i am changing!'
//'i am been getting'
//'bye!?'這只是一個(gè)惡作劇,讓屬性在修改和獲取的時(shí)候都進(jìn)行了修改,不過(guò)這確實(shí)是一個(gè)很強(qiáng)大的功能,我們可以通過(guò)這個(gè)方法實(shí)現(xiàn)頁(yè)面展現(xiàn)與數(shù)據(jù)的綁定,讓你的關(guān)注點(diǎn)集中在數(shù)據(jù)而不是數(shù)據(jù)的展現(xiàn)過(guò)程,這就是所謂的"雙向綁定"
比如這樣:
var demo = {}
var v;
Object.defineProperty(demo,'foobar',{
get:function(){
return v;
},
set:function(e){
v = e;
sow();
}}
);
function sow(){
$('body').html(demo.foobar)
}
demo.foobar = "hello"
setTimeout(function(){
demo.foobar = "bye"
setTimeout(function(){
demo.foobar = 'i am back'
},1000)
},1000)這個(gè)例子中,數(shù)據(jù)的展現(xiàn)交給了sow()去做,數(shù)據(jù)這邊每次更新demo.foobar的值,展現(xiàn)就會(huì)更新,這一切都得益于 Object.defineProperty
最后的話Object.defineProperty是ECS5屬性,所以IE8以下無(wú)效。
更多請(qǐng)見(jiàn)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
以上就是使用Object.defineProperty為對(duì)象定義屬性的詳細(xì)內(nèi)容,更多關(guān)于Object.defineProperty定義對(duì)象屬性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
兼容ie ff div 層 打開(kāi)+關(guān)閉+ 拖動(dòng)+遮罩+移動(dòng)+動(dòng)畫改變高寬
div層 打開(kāi)+關(guān)閉+ 拖動(dòng)+遮罩+移動(dòng)+動(dòng)畫改變高寬的實(shí)例js代碼2008-07-07
js實(shí)現(xiàn)杯子倒水問(wèn)題自動(dòng)求解程序
智力測(cè)試題經(jīng)常遇到類似的邏輯題,給幾個(gè)容量不等的杯子,讓你倒出多少的水,感興趣的朋友可以參考下哈希望可以幫助到你2013-03-03
使用JavaScript獲取當(dāng)前日期時(shí)間及其它操作
在 JavaScript 中,處理“當(dāng)前日期和時(shí)間”是非常常見(jiàn)的需求,本文為大家詳細(xì)介紹了JavaScript 獲取當(dāng)前日期時(shí)間及其它操作,包括格式化,加減時(shí)間,時(shí)間戳轉(zhuǎn)換等2025-08-08
基于JavaScript實(shí)現(xiàn)輪播圖效果
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01
javascript對(duì)象的property和prototype是這樣一種關(guān)系
javascript對(duì)象的property和prototype是這樣一種關(guān)系...2007-03-03
javascript實(shí)現(xiàn)checkBox的全選,反選與賦值
這篇文章主要介紹了javascript實(shí)現(xiàn)checkBox的全選,反選與賦值的方法,以實(shí)例形式詳細(xì)分析了實(shí)現(xiàn)的思路及對(duì)應(yīng)的html與js代碼的實(shí)現(xiàn)過(guò)程2015-03-03

