使用Object.defineProperty為對象定義屬性
引言
Object.defineProperty
,顧名思義,為對象定義屬性,但是疑問是,我們有太多的辦法去定義一個對象的屬性了,比如foo['bar'] = 100
,比如foo.bar = 100
,為什么還要用它?會不會是自找麻煩呢?
使用Object.defineProperty
的原因很簡單,因為只有通過它才能定義一些值得特殊屬性,比如是否可寫,是否可枚舉,接下來我們用例子來看一下。
定義或修改屬性
var demo = { foo:1, bar:2 }; Object.defineProperty(demo, 'foo',{ value:100 }); Object.defineProperty(demo, 'foobar',{ value:"hello" });
這個例子中,第一個修改了demo的屬性foo,第二個創(chuàng)建了foobar屬性,屬性的值是第三個參數(shù)中value。第一個參數(shù)是要修改的對象,第二個參數(shù)是屬性名,第三個參數(shù)是“描述”,一個可以對屬性進行一些設(shè)定的鍵值對。
所以,如果你想讓一個屬性變得不可枚舉,要這么寫
Object.defineProperty(demo, 'foobar',{ value:"hello", enumerable:false });
可枚舉的屬性
上一個例子其實是沒有意義的,因為enumerable
的默認值就是false,用上述方法創(chuàng)建的屬性默認就是不可枚舉,那么什么是不可枚舉呢?很簡單,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)建對象的屬性,則這個屬性的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
相當于 .
和[]
的一個加強版,但是另外一個因素也讓他變得更強大。
屬性的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!?'
這只是一個惡作劇,讓屬性在修改和獲取的時候都進行了修改,不過這確實是一個很強大的功能,我們可以通過這個方法實現(xiàn)頁面展現(xiàn)與數(shù)據(jù)的綁定,讓你的關(guā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)
這個例子中,數(shù)據(jù)的展現(xiàn)交給了sow()去做,數(shù)據(jù)這邊每次更新demo.foobar的值,展現(xiàn)就會更新,這一切都得益于 Object.defineProperty
最后的話Object.defineProperty
是ECS5屬性,所以IE8以下無效。
以上就是使用Object.defineProperty為對象定義屬性的詳細內(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-08