本文是js紅寶書第八章總結(jié)
屬性的兩種類型
內(nèi)部特性用來描述屬性的特征谱轨,無法直接訪問(要通過訪問器)戒幔,以[[]]進(jìn)行標(biāo)識
特性就是為了某個(gè)概念而定義的專一的東西,不能把屬性看作是數(shù)據(jù)屬性+訪問器屬性組成的對象
- 數(shù)據(jù)屬性
- [[Configurable]]是否可以delete诗茎,是否可以改為訪問器屬性,一般為true
- [[Enumberable]]是否可以通過for-in循環(huán)返回献汗,一般都是true
- [[Writable]]值是否能被修改
- [[Value]]
簡單點(diǎn)說敢订,這些特性用來描述
舉個(gè)例子:person.name = "lpj"
name的數(shù)據(jù)屬性的[[value]]就是"lpj" ,但你不能直接用[]獲取罢吃,這些內(nèi)部特性是工具人,用來描述數(shù)據(jù)的
可以用Object.defineProperty方法進(jìn)行修改默認(rèn)值
注意:把屬性定義為不可配置后尿招,就不能變回可配置的了
- 訪問器屬性
不包含數(shù)據(jù)矾柜,包含一個(gè)獲取(getter)函數(shù)和設(shè)置(setter)函數(shù) 以下屬性描述他們的行為- [[Configurable]]
- [[Enumerable]]
- [[Get]]方法 讀取屬性值
- [[Set]]方法 修改屬性值
典型訪問器屬性應(yīng)用場景怪蔑,即設(shè)置一個(gè)屬性值會(huì)導(dǎo)致一些變化發(fā)生
let book = {
year_:2021,//偽私有成員(指該屬性需用set函數(shù)進(jìn)行操作)
edition:1
}
Object.defineProperty(book,"year",{
/*這里會(huì)新增year屬性缆瓣,
但由于使用了definePropert弓坞,
這個(gè)屬性會(huì)被覆寫為如下的內(nèi)部特性(由于沒設(shè)置[[Value]] 它也就沒有數(shù)據(jù)值啦隧甚,單純是工具人訪問year_)*/
get(){
//簡單返回屬性值
return this.year_;
},
set(newValue){
//對寫入的值進(jìn)行處理 注意如果寫為空的話 就是只讀屬性了
if (newValue>2021) {
this.year_ = newValue
this.edition++
}
else
this.year_ = newValue
}
})
console.log(book.year)//值為2021,edition=1
book.year = 2077;//嘗試修改year,會(huì)被Editon記錄菩帝,當(dāng)然這里你直接修改year_的話就沒轍了
console.log(book.year)//edition=2
為什么console看對象時(shí)看不到原來的屬性值,而總是顯示最新的值茬腿?
Simply what it says is that the console evaluated the object just as you press the expand icon. Here is a test.
1:Type o = {} in the console. The output will be something like >{}. DON'T EXPAND YET!
2:Add a property to the o object. o.x = 1
3:Now go back and expand the previous output. It will have the x property you added obviously after that output was created. But the the output still have the x val
——Stack Overflow
可以通過Object.define-Properties()實(shí)現(xiàn)一次性同時(shí)定義多個(gè)多個(gè)屬性
- ES6對象拓展方法
- 通過getOwnPropertyDescriptor()讀取屬性的特性
- 合并對象:
Object.assign(dest, src)
把src復(fù)制進(jìn)dest - 對象相等精確判定Object.is() 與===很像
- 可計(jì)算屬性呼奢,es6可以在字面量直接進(jìn)行動(dòng)態(tài)命名屬性
let nameKey = name
let person = {
[nameKey] = 'lpj'
}
console.log(person.name=='lpj')//true
//以前必須先聲明對象
//再person[nameKey] = 'hjy'這樣
這意味著可以使用復(fù)雜表達(dá)式甚至是函數(shù),但要小心表達(dá)式副作用切平,如果拋出錯(cuò)誤會(huì)導(dǎo)致對象創(chuàng)建中斷握础,且不可回滾
- 對象解構(gòu)
let person = {
name:'pj',
age:19
}
//不使用解構(gòu)
let personName = person.name
let personAge = person.age
//使用解構(gòu)語法
let { name:personName , age: personAge} = person;
//注意冒號前后
解構(gòu)在紅寶書中篇幅蠻大的,其語法和用法比較多變