js物件可擴充套件性和屬性的四個特性(上)
阿新 • • 發佈:2019-12-08
# js物件可擴充套件性和屬性的四個特性(上)
一、前言
再次花時間回顧一下基礎,畢竟要想樓建的好,地基就要牢固,嘻嘻!
- 在開始之前需要具備對prototype、__proto__、constructor有一定得了解,可以看看我之前寫的一篇文章=>通道
- 之前的使用者管理系統已經差不多了,順便加了個socket聊天的,但是由於做java後臺的哪個朋友節奏跟不上來,所以即時聊天的後臺就是node+socket-io寫的,由於使用者列表也涉及比較多的使用者隱私問題,所以我設定了頁面許可權和介面許可權,然後下面開放的幾個賬號就只能看到幾個頁面而已,哈哈。=>通道
- 體驗賬號1:賬號:“123456”。密碼:“123456”
體驗賬號2:賬號:“123123”。密碼:“123123”
二、目錄
- 物件屬性的四個特性
- 物件的可擴充套件性
- 刪除屬性
- 檢測屬性
- 列舉屬性
- 屬性的getter和setter
三、物件屬性的四個特性
1、定義
1.1、什麼是資料屬性?
資料屬性就是我們平常看到的物件普通屬性。
資料屬性的特性為以下四種:
值(value)
可寫性(writable)
可列舉性(enumerable)
可配置性(configurable)
1.2、什麼是儲存器屬性?
儲存器屬性是由getter和setter定義的屬性
儲存器屬性特性為以下四種:
讀取(get) 寫入(set) 可列舉性(enumerable) 可配置性(configurable)
2、方法
2.1、獲取某個物件特定屬性的屬性描述
Object.getOwnPropertyDescriptor()
const log = console.log; //返回資料資料的描述 let aa = { x: 1 }; log(Object.getOwnPropertyDescriptor(aa, 'x')) //返回儲存器屬性的描述 let bb = { get y() { return 2; }, } log(Object.getOwnPropertyDescriptor(bb, 'y')) //對於一個不存在的屬性或者繼承屬性返回undefined log(Object.getOwnPropertyDescriptor({}, 'x')) log(Object.getOwnPropertyDescriptor({}, 'toString'))
2.2、讓新建屬性具有某種特性
Object.defineProperty()
說明:
- defineProperty不能修改繼承屬性
- defineProperty不必包含所有四個屬性,對於已有的屬性來說,未指定的特性不做修改,只對指定特性進行修改。
- 對於新建立的屬性來說預設是false或者undefined。
- 當configurable設定為false,就不能再設定為true了,因為不可配置也不能配置自己
- 當configurable設定為true,writable設定為false時,是可以通過配置特性更改value值的
- 當configurable設定為false時,writable可以從true設定為false,當時不能從false設定為true
const log = console.log;
var aa = {
y: 22
};
//新增一個x屬性為不可寫、不可列舉、可配置
Object.defineProperty(aa, 'x', {
value: 1,
writable: false,
enumerable: false,
configurable: true
})
log(aa.x);
aa.x = 2; //嘗試修改這個屬性會失敗,但是不會報錯,在嚴格模式下會報錯
log(aa.x)
for (let i in aa) {
//不可列舉資料屬性x,但是y可以列舉
console.log(i)
}
//因為這個x屬性依然是可以配置的,所以可以通過配置的方式對值進行修改
Object.defineProperty(aa, 'x', {
value: 3,
})
log(aa.x);
//將資料屬性設定為儲存器屬性
Object.defineProperty(aa, 'x', {
get: function() {
return 4;
},
})
log(aa.x)
2.3、同時修改多個屬性的特性
Object.defineProperties()
const log = console.log;
var aa = {};
Object.defineProperties(aa, {
x: {value: 1,writable: false,enumerable: true,configurable: false},
y: {value: 2,writable: false,enumerable: true,configurable: false},
z: {
get:function(){
return 3
},
enumerable: false,
configurable: false
}
})
for(let i in aa){
log(i,'---',aa[i])
}
log('z','---',aa.z)
四、物件的可擴充套件性
1、定義
1.1、什麼是可擴充套件性?
物件可擴充套件性是指是否可以給該物件新增新的屬性
2、方法
2.1、將物件設定為不可擴充套件
Object.preventExtensions()
說明:
- 物件一旦設定不為不可擴充套件就不能轉換為可擴充套件了
- Object.preventExtensions只會影響物件本身的可擴充套件性,所以依然還是可以給物件原型新增屬性。
const log = console.log;
var aa = {};
Object.preventExtensions(aa);
aa.x = 1;
log(aa.x)
2.2、檢測物件是否是可擴充套件的
Object.isExtensible()
//在《javascript權威指南》第六版中6.8.3節介紹可擴充套件性的時候,將isExtensible寫為esExtensible了。
const log = console.log;
var aa = {};
var bb = {};
Object.preventExtensions(aa);
log(Object.isExtensible(aa))
log(Object.isExtensible(bb))
2.3、將物件封閉(sealed)
Object.seal()
說明:
- Object.seal不僅可以設定物件的可擴充套件性,還可以設定物件的所有自有屬性的可配置性
- 將物件設定為不可擴充套件並且不可配置,也就是說不能給這個物件新增新屬性,而且已有的屬性不能刪除或者配置。
- 不過這些屬性可寫特性依然是可以配置的
const log = console.log;
var aa = {
y: 2
};
Object.seal(aa);
aa.x = 1;
log(aa.x);
log(Object.getOwnPropertyDescriptor(aa, 'y'))
Object.defineProperty(aa, 'y', {
writable: false,
})
log(Object.getOwnPropertyDescriptor(aa, 'y'))
2.4、檢測物件是否被封閉
Object.isSealed()
const log = console.log;
var aa = {};
var bb = {};
Object.seal(aa);
log(Object.isSealed(aa));
log(Object.isSealed(bb))
2.5、將物件凍結(freeze)
Object.freeze()
說明:
- freeze不僅僅可以將物件設定為不可擴充套件和所有屬性為不可配置,並且會將所有物件屬性設定為只讀。
- 如果存取器屬性具有setter方法,則不會受到影響,仍然可以通過此方法給屬性賦值。
const log = console.log;
var aa = {
x: 1
};
Object.freeze(aa);
log(Object.getOwnPropertyDescriptor(aa, 'x'))
2.6、檢測物件是否配凍結
Object.isFreeze()
const log = console.log;
var aa = {};
var bb = {};
Object.freeze(aa);
log(Object.isFrozen(aa));
log(Object.isFrozen(bb));