javascript-object對象屬性操作之Object.defineProperty
阿新 • • 發佈:2019-05-13
終極 {} name屬性 ble -o 常量 沒有 tab 是否
一、基本用法簡介
聲明一個簡單的對象,如下
var obj = { name: ‘ldld‘ }
我們可以用Object.defineProperty來聲明這個對象
var obj = {} Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:true, enumerable: true, configurable: true })
下列就這四個基本的配置簡單介紹一下
- value:初始值
-
writable:是否可以修改該屬性的值
var obj = {} Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:false, enumerable: true, configurable: true }) obj.name // ‘ldld‘ obj.name = ‘LLLL‘; // 這裏會修改失敗,嚴格模式下會報錯 TypeError console.log(obj.name) // ‘ldld‘
- enumerable:是否可枚舉,這個是否能遍歷到該屬性(for)
-
configurable : 這個得重點講一下
var obj = {} // 第一次設置操作configurable配置,設置為false Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:true, enumerable: true, configurable: false }) obj.name // ‘ldld‘ obj.name = ‘LLLL‘; // configurable: false 不影響writable屬性,這裏可以設置成功 console.log(obj.name) // ‘LLLL‘ // 第二次設置操作configurable配置,在第一步false基礎上改回true Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:true, enumerable: true, configurable: true // 現在我們想改回來,但是很遺憾,不能。不管是嚴格模式還是非嚴格模式都會報錯 })
此外,configurable會影響該對象屬性是否可以被刪除
Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:true, enumerable: true, configurable: true }) delete obj.name; console.log(obj.name) // undefined ,說明刪除成功 Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:true, enumerable: true, configurable: false }) delete obj.name; console.log(obj.name) // ldld, 說明name屬性沒有被刪除
二、對象常量
const str = ‘abc‘; str = ‘def‘; // 報錯Uncaught TypeError: Assignment to constant variable. const obj = {name:‘ldld‘}; obj.name = { name:‘ldld1234‘ // 這裏會修改成功 }
const聲明的對象不可變,實際上是可以理解為指針的不可變。
const str = ‘abc‘; 表示str指針指向棧中一個地址,值‘abc‘;
str = ‘def‘;表示str又指到另一個地址,值為‘def‘,違反了不可變的規則,報錯了。
const obj = {name:‘ldld‘};表示obj 對象指向一個堆 內存堆的obj的引用,不管怎麽改變obj裏面的值,在內存堆中地方始終不變,因此不會報錯。
那麽問題來了,我們想聲明一個不可變的對象,那怎麽辦?可以參考如下:
var obj = {} Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:false, configurable: false }) // 此時問obj的name屬性不可改變了。
但是問題來來,name是不能再改變,但是我們可以給對象擴展其他屬性。。。
三、防止對象擴展Object.preventExtensions
var obj = {} Object.defineProperty(obj,‘name‘,{ value:‘ldld‘, writable:false, configurable: false }) // 此時問obj的name屬性不可改變了。但是可以擴展obj屬性 obj.age = 100; console.log(obj.age) // 100 Object.preventExtensions(obj); obj.sex = ‘male‘; console.log(obj.sex) // undefined,說明擴展失敗
四、密封Object.seal
顧名思義,密封一個對象,這個對象不能配置,不能擴展屬性,不能刪除屬性。但是可以可以修改熟悉過的值
Object.seal(obj)// 等同於如下:代碼1 + 代碼2 // 代碼1 Object.defineProperty(obj,‘[該對象所有的屬性]‘,{ configurable: false // writable:true, // 此時默認為true,可以修改 }) // 代碼2 Object.preventExtensions(obj);
四、凍結Object.freeze(obj)
Object.freeze(obj)// 等同於如下:代碼1 + 代碼2 // 代碼1 Object.seal(obj) // 代碼2 Object.defineProperty(obj,‘[該對象所有的屬性]‘,{ writable:false })
由此可見,凍結,就是定一個對象常量的終極大法。
javascript-object對象屬性操作之Object.defineProperty