使用Object.defineProperty為對象定義屬性
引言
Object.defineProperty
,顧名思義,為對象定義屬性,但是疑問是,我們有太多的辦法去定義一個(gè)對象的屬性了,比如foo['bar'] = 100
,比如foo.bar = 100
,為什么還要用它?會不會是自找麻煩呢?
使用Object.defineProperty
的原因很簡單,因?yàn)橹挥型ㄟ^它才能定義一些值得特殊屬性,比如是否可寫,是否可枚舉,接下來我們用例子來看一下。
定義或修改屬性
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ù)是要修改的對象,第二個(gè)參數(shù)是屬性名,第三個(gè)參數(shù)是“描述”,一個(gè)可以對屬性進(jìn)行一些設(shè)定的鍵值對。
所以,如果你想讓一個(gè)屬性變得不可枚舉,要這么寫
Object.defineProperty(demo, 'foobar',{ value:"hello", enumerable:false });
可枚舉的屬性
上一個(gè)例子其實(shí)是沒有意義的,因?yàn)?code>enumerable的默認(rèn)值就是false,用上述方法創(chuàng)建的屬性默認(rè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)建對象的屬性,則這個(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
通過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)行了修改,不過這確實(shí)是一個(gè)很強(qiáng)大的功能,我們可以通過這個(gè)方法實(shí)現(xiàn)頁面展現(xiàn)與數(shù)據(jù)的綁定,讓你的關(guān)注點(diǎn)集中在數(shù)據(jù)而不是數(shù)據(jù)的展現(xiàn)過程,這就是所謂的"雙向綁定"
比如這樣:
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)就會更新,這一切都得益于 Object.defineProperty
最后的話Object.defineProperty
是ECS5屬性,所以IE8以下無效。
以上就是使用Object.defineProperty為對象定義屬性的詳細(xì)內(nèi)容,更多關(guān)于Object.defineProperty定義對象屬性的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript 動態(tài)改變層的Z-INDEX的代碼style.zIndex
javascript 動態(tài)改變層的Z-INDEX的代碼style.zIndex...2007-08-08javascript實(shí)現(xiàn)簡單留言板案例
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)簡單留言板案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02