屬性的簡(jiǎn)寫方法
var name = '秦司令';
var json = {name} // name:'秦司令'
上面代碼中,變量在對(duì)象中當(dāng)做屬性名,屬性值就是變量的值,這就是屬性的簡(jiǎn)寫方式芹关。
var age = 19
var obj = {
name:'秦司令',
age
}
console.log(obj) // {name:'秦司令',age:19}
函數(shù)中的聲明的對(duì)象也能簡(jiǎn)寫
function example(x,y){
return {x,y}
}
console.log(example(1,2)) // {x:1,y:2}
上面代碼如果不傳參,x和y的參數(shù)就是undefined。
對(duì)象里面的函數(shù)也可以簡(jiǎn)寫伊履。
var json = {
add(){
alert(1)
}
}
// 上面的方法等同于下面
var json = {
add:function(){
alert(1)
}
}
簡(jiǎn)寫一個(gè)Generator函數(shù),前面需要要加上 * 號(hào)
var obj = {
* add(){
yiled 'hello word'
}
}
上面代碼中,Generator函數(shù)等下一期跟你們分享,詳細(xì)講解。
屬性名表達(dá)式
js定義對(duì)象有兩種方式
var obj = {}
obj.name = '秦司令';
obj['a' + 'ge'] = 19;
上面代碼中,方法一是用標(biāo)識(shí)符作為對(duì)象屬性名,方法二是用表達(dá)式作為屬性名,這是將表達(dá)式方在中括號(hào)內(nèi),中括號(hào)內(nèi)可以寫變量,請(qǐng)看下面代碼酣栈。
let age = 'age';
var json = {
[age] :19,
['a' + 'bc'] : 123
}
console.log(json) // {age:19,abc:123}
表達(dá)式還可以用于定義方法名透且。
var obj = {
['a' + 'bc'](){
return 'abc'
}
}
console.log(obj.abc()) // abc
注意,對(duì)象的簡(jiǎn)寫不能和表達(dá)式一起使用,會(huì)報(bào)錯(cuò)。
var name = '秦司令';
console.log({ [name] }) // 報(bào)錯(cuò)
console.log({ [name] : 123 }) // 秦司令:123
如果屬性表達(dá)式是一個(gè)對(duì)象的話,默認(rèn)情況下會(huì)自動(dòng)轉(zhuǎn)為字符串,[object Object] 窿吩。
var dx = {}
var json = {
[dx]:123
}
console.log(json) // {[object Object] :123}
方法name的屬性
函數(shù)的name屬性,返回函數(shù)名,對(duì)象方法也是函數(shù),因此也有name屬性。
var obj = {
add(){
return 123
}
}
console.log(obj.add.name) // add
上面代碼,方法add的name屬性就是函數(shù)名,add错览。
函數(shù)name屬性有兩種特殊情況,bind方法創(chuàng)造的函數(shù),name屬性返回 bound 加上函數(shù)名 ;Function 構(gòu)造函數(shù)創(chuàng)造的函數(shù),name屬性返回anonymous 英語(yǔ)意思為(匿名的)
(new Function()).name // anonymous
function abc(){}
console.log(abc.bind().name) // bound abc
如果對(duì)象方法是一個(gè)Symbol值,那么name屬性返回的就是這個(gè)Symbol值的描述纫雁。
var s = Symbol('foo')
var s1 = Symbol()
let obj = {
[s](){},
[s1](){}
}
console.log(obj[s].name) // ['foo']
console.log(obj[s1].name) // ""
上面代碼中,s對(duì)應(yīng)的Symbol值有描述,s1沒有
屬性的可枚舉性和遍歷
可枚舉性
對(duì)象的每個(gè)屬性都有一個(gè)描述對(duì)象(Descriptor),用來(lái)控制該屬性的行為。
Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對(duì)象倾哺。
let obj = {foo:123};
Object.getOwnPropertyDescriptor(obj,'foo');
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
描述對(duì)象的enumerable屬性稱為 "可枚舉性" , 如果該屬性為false,就表示某些操作會(huì)忽略當(dāng)前屬性轧邪。
目前,有四種操作會(huì)忽略enumerable為false屬性
for..in循環(huán):只遍歷對(duì)象自身和繼承的可枚舉性的屬性
Object.keys() : 返回對(duì)象自身的所有可枚舉屬性的鍵名
JSON.stringify() : 只轉(zhuǎn)換自身的可枚舉性的屬性
Object.assign() : 忽略enumerable為false的屬性,只拷貝對(duì)象自身的可枚舉性的屬性
var json1 = {name:'秦司令'}
Object.defineProperty(json1,'age',{
value:19,
enumeable:false
})
for(var i in json1){
console.log(i) // name
};
console.log(Object.keys(json1)) // ['name']
console.log(JSON.stringify(json1)) // {"name":"秦司令"}
console.log(Object.assign({},json1)) // {name: "秦司令"}
上面代碼中,都獲取不到enumerable為false的屬性,Object.defineProperty是專門設(shè)置描述對(duì)象的屬性;
屬性的遍歷
Object.getOwnPropertyNames(obj)
該方法返回一個(gè)數(shù)組,包含自身的所有屬性(不包含Symbol屬性,但是包括不可枚舉屬性)的鍵名
var json1 = {name:'秦司令'}
Object.defineProperty(json1,'age',{
value:19,
enumeable:false
})
console.log(Object.getOwnPropertyNames(json1)) // ["name", "age"]
Object.getOwnPropertySymbols(obj)
該方法返回一個(gè)數(shù)組,包含對(duì)象自身的所有 Symbol 屬性的鍵名,只返回Symbol的鍵名羞海。
var jsonArr = {[Symbol('123')]:1,b:2,c:9,3:'d',[Symbol()]:123}
console.log(Object.getOwnPropertySymbols(jsonArr)) // [Symbol(123), Symbol()]
Reflect.ownKeys(obj)
該方法返回一個(gè)數(shù)組忌愚,包含對(duì)象自身的所有鍵名,不管鍵名是 Symbol 或字符串却邓,也不管是否可枚舉硕糊。
var jsonArr = {[Symbol('123')]:1,b:2,c:9,3:'d',[Symbol()]:123}
console.log(Reflect.ownKeys(jsonArr)) // ["3", "b", "c", Symbol()]
上面代碼中,Reflect.ownKeys該方法返回一個(gè)數(shù)組,返回所有的屬性,這個(gè)數(shù)組的順序是這樣的,首先是數(shù)值屬性,然后是字符串,按照字符串的位置加入,最后是Symbol屬性
super關(guān)鍵字
Object.prototype.name = 'lider'
var json = {
name:'我是json',
add(){
return super.name;
}
}
console.log(json.add());
上面代碼中,super該方法是指向Object的原型。
看下面的列子
var obj = {
name:'我是obj',
na(){
console.log(this.name)
}
}
var json = {
name:'我是json',
add(){
return super.name;
}
}
Object.setPrototypeOf(json,obj)
console.log(json.add()); // 我是obj
上面的代碼,把json的原型改成了obj的原型,所以name屬性就指向obj里面的。
super該方法現(xiàn)正只能,用在對(duì)象的簡(jiǎn)寫方法內(nèi)容癌幕。
// 報(bào)錯(cuò)
const obj = {
foo: super.foo
}
// 報(bào)錯(cuò)
const obj = {
foo: () => super.foo
}
// 報(bào)錯(cuò)
const obj = {
foo: function () {
return super.foo
}
}
對(duì)象的擴(kuò)展運(yùn)算符
Es2018將擴(kuò)展運(yùn)算符引入了對(duì)象衙耕。
var [a...b] = [1,2,3]
a //1
b // 2 3
解構(gòu)賦值
對(duì)象的解構(gòu)賦值用于從一個(gè)對(duì)象取值,相當(dāng)于將目標(biāo)對(duì)象自身所有可遍歷屬性(包括enumerable),但尚未被讀取的屬性,分配到指定的對(duì)象上面,所有的鍵和它們的值,都會(huì)拷貝到新對(duì)象上面昧穿。
let {x,y...z} = {x:1,y:2,c:3,d:4}
x // 1
y // 2
z // {c:3,d:4}
上面代碼中,變量z是解構(gòu)賦值所在的對(duì)象,它獲取等號(hào)右邊尚未讀取的值,并且將(鍵值和屬性值) 一同拷貝過(guò)來(lái)
解構(gòu)賦值要求等號(hào)右邊必須是對(duì)象,如果不是對(duì)象,就會(huì)強(qiáng)制轉(zhuǎn)換為對(duì)象,undefined和null無(wú)法轉(zhuǎn)換為對(duì)象,所以它們會(huì)報(bào)錯(cuò)勺远。
let {...z} = null;
let {...a} = undefined
解構(gòu)賦值必須最后一個(gè)參數(shù)是擴(kuò)展運(yùn)算符,否則會(huì)報(bào)錯(cuò)。
let {...a,b} = {a:1,b:2}
注意,解構(gòu)賦值的拷貝是淺拷貝,即如果一個(gè)鍵值的是數(shù)組或者是對(duì)象,那么解構(gòu)賦值拷貝的是這個(gè)值的引用,而不是這個(gè)值的副本时鸵。
let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b // 2
另外,擴(kuò)展運(yùn)算符的解構(gòu)賦值,不能復(fù)制繼承的原型胶逢。
let o1 = { a: 1 };
let o2 = { b: 2 };
o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined
如果擴(kuò)展運(yùn)算符后面是一個(gè)對(duì)象,則沒有任何效果。
console.log( {...{} , a:123 } ) // {a:123}
如果擴(kuò)展運(yùn)算符后面不是對(duì)象,則會(huì)自動(dòng)將其轉(zhuǎn)為對(duì)象饰潜。
console.log({...1}) // {}
上面代碼中,將其轉(zhuǎn)換為對(duì)象 包裝類Number{1} ,因此它沒有屬性則返回空對(duì)象初坠。
如果擴(kuò)展運(yùn)算符后面是字符串,它會(huì)自動(dòng)轉(zhuǎn)成一個(gè)類似數(shù)組的對(duì)象彭雾,因此返回的不是空對(duì)象碟刺。
{...'hello'}
// {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
擴(kuò)展運(yùn)算符的參數(shù)之中,如有取值函數(shù)get,這個(gè)函數(shù)是會(huì)執(zhí)行的。
let abc = {
get aa(){
return 1
}
}
console.log(abc)
let abc1 = {
...{
get aa(){
return '我自動(dòng)執(zhí)行'
}
}
}
console.log(abc1)