原創(chuàng)文章&經(jīng)驗(yàn)總結(jié)&從校招到A廠一路陽光一路滄桑
詳情請戳www.codercc.com
主要知識點(diǎn)有對象類別、屬性速記法、方法簡寫、需計(jì)算屬性名、Object.is()方法、Object.assign()方法、可允許重復(fù)的屬性、自有屬性的枚舉順序、Object.setPrototypeOf()方法、super引用、方法定義
1. 對象類別
對象有以下幾種類別:
- 普通對象:擁有JS對象所有默認(rèn)的內(nèi)部行為;
- 奇異對象:其內(nèi)部行為在某些方面有別于默認(rèn)行為;
- 標(biāo)準(zhǔn)對象:在ES6中被定義的對象,例如Array,Date等;
- 內(nèi)置對象:在腳本開始運(yùn)行的時(shí)候由JS運(yùn)行環(huán)境提供的對象,所有的標(biāo)準(zhǔn)對象都是內(nèi)置對象
2. 對象字面量語法的擴(kuò)展
屬性初始化的速記法
屬性初始化器的速記法可以用來消除屬性名和本地變量的重復(fù)情況,可以使用作用域內(nèi)的變量值賦值給同名屬性:
function createPerson(name,age){
return {
name:name,
age:age
}
}
//由于屬性名和本地變量名相同,可以采用
//屬性初始化器的速記法,等價(jià)于
function createPerson(name,age){
return {
name,
age
}
}
方法簡寫
在對象字面量的寫法中,為一個(gè)對象添加一個(gè)方法,需要指定對象的屬性以及具體的函數(shù)聲明。ES6提供了一種方法簡寫語法,通過省略function關(guān)鍵字,能夠讓為對象添加方法的語法更加簡潔。有一個(gè)重要的區(qū)別是:方法簡寫能夠使用super
,而非簡寫的方法不能使用super
。
//方法簡寫法
let person = {
sayName:function(){
return name;
}
}
//等價(jià)于
let person = {
sayName(){
return name;
}
}
需計(jì)算屬性名
需計(jì)算屬性名規(guī)則允許對象字面量中屬性名是變量、字符串字面量或者由變量計(jì)算而得的,具體寫法是通過方括號[]包含屬性名。
//需計(jì)算屬性名
let person = {};
let firstName = 'first name';
let suffix = '@github.com'
let email = 'email';
//變量
person[firstName] = 'hello';
//字符串字面量
person['last name']= 'world';
//變量計(jì)算而得到的
person[email+suffix] = 'example@github.com'
Object.is()
JS中比較兩個(gè)值是否相同的時(shí)候會使用嚴(yán)格等于運(yùn)算符===
,但是,使用嚴(yán)格運(yùn)算符式,+0和-0會認(rèn)為這兩者是相等的,而NaN===NaN
是不相等的,使用Object.is()方法來判斷這兩者情況與使用嚴(yán)格相等符會有所不同,其他情況和使用嚴(yán)格相等運(yùn)算符基本一致;
console.log(+0==-0); //true
console.log(+0===-0); //true
console.log(Object.is(+0,-0)); //false
console.log(NaN==NaN); //false
console.log(NaN===NaN); //false
console.log(Object.is(NaN,NaN)); //true
console.log(5=='5'); //true
console.log(5==='5'); //false
console.log(Object.is(5,'5')) //false
Object.assign()
一個(gè)對象從另外一個(gè)對象獲取屬性和方法,這是典型的混入(Mixin)模式,Object.assign()方法可以更簡潔的實(shí)現(xiàn)對象混入,該方法需要一個(gè)接受者對象和若干個(gè)供應(yīng)者對象。接收者會按照供應(yīng)者在參數(shù)中的順序來依次接收它們的屬性,這意味著,第二個(gè)供應(yīng)者可能會覆蓋第一個(gè)供應(yīng)者相同的屬性;
let person={
name:'hello',
age:18
}
let car ={
brand:'BWM',
age:5
}
let obj = {};
Object.assign(obj,person,car);
console.log(obj); //{name: "hello", age: 5, brand: "BWM"}
Object.assign()方法并未在接受者上創(chuàng)建訪問器屬性,即使供應(yīng)者擁有訪問器屬性,由于Object.assign()方法使用賦值運(yùn)算符,供應(yīng)者的訪問器屬性會轉(zhuǎn)換成接受者的數(shù)據(jù)屬性;
let receiver = {},
supplier = {
get name() {
return "file.js"
}
};
Object.assign(receiver, supplier);
let descriptor = Object.getOwnPropertyDescriptor(receiver, "name");
console.log(descriptor.value); // "file.js"
console.log(descriptor.get); // undefined
允許重復(fù)的屬性
在ES5嚴(yán)格模式下,為對象字面量中屬性會檢查是否重復(fù),如果重復(fù)的話就會拋出一個(gè)錯(cuò)誤。而在ES6中,無論是在嚴(yán)格模式下還是非嚴(yán)格模式下,都不再檢查屬性是否重復(fù),當(dāng)屬性重復(fù)的時(shí)候,后面的屬性會覆蓋前面的屬性;
//重復(fù)的屬性
let person = {
name:'hello',
name:'world'
}
console.log(person.name); //world
自有屬性的枚舉順序
ES6規(guī)定了自有屬性的枚舉順序,會依次按照數(shù)字類型鍵->字符串類型鍵->符號類型鍵的枚舉順序:
- 所有的數(shù)字類型鍵,按升序排列;
- 所有的字符串類型鍵,按被添加到對象的順序排列;
- 所有的符號類型,也按添加順序排列
//自有屬性的枚舉順序
var obj = {
a: 1,
0: 1,
c: 1,
2: 1,
b: 1,
1: 1
};
obj.d = 1;
console.log(Object.getOwnPropertyNames(obj).join(""));//012acbd
3. 更強(qiáng)大的原型
修改對象原型
在ES6中可以通過Object.setPrototypeOF()方法修改對象的原型,該方法包含了兩個(gè)參數(shù):一個(gè)是被修改原型的對象,一個(gè)是將被指定的原型;
let person = {
getName(){
return 'hello';
}
}
let dog ={
getName(){
return 'world';
}
}
let friend = Object.create(person);
console.log(friend.getName()); //hello
console.log(Object.getPrototypeOf(friend)===person); //true
Object.setPrototypeOf(friend,dog);
console.log(friend.getName()); //world
console.log(Object.getPrototypeOf(friend)===dog); //true
使用super引用
能夠使用super
引用,來訪問原型中的方法,假如需要覆蓋對象中的同名方法可以這樣做:
let person = {
getName(){
return 'hello';
}
}
let dog ={
getName(){
return super.getName()+' world';
}
}
Object.setPrototypeOf(dog,person);
console.log(dog.getName()); //hello world
如果使用super引用的話,只能在方法簡寫中才能使用,否則就會報(bào)錯(cuò):
let dog ={
getNanem:function (){
return super.getName()+' world';
}
}
報(bào)錯(cuò):Uncaught SyntaxError: 'super' keyword unexpected here
方法定義
在ES6之前,方法的概念從未被正式定義,而在ES6中做出了正式定義:方法是擁有一個(gè)[[HomeObject]]內(nèi)部屬性的函數(shù),此內(nèi)部屬性指向該方法所屬的對象;
//方法
let person = {
getName(){
return 'hello';
}
}
//不是方法
function getName(){
return 'hello world';
}
4. 總結(jié)
ES6通過對對象功能的擴(kuò)展,讓ES6更加簡單易用和更加強(qiáng)大,在對象功能上具體有這樣一些改進(jìn):
針對對象字面量:
- 速記法屬性能夠更加輕易的將作用域內(nèi)的變量值賦值給同名屬性;
- 需計(jì)算屬性名規(guī)則能夠更方便的將,變量、字符串字面量以及通過變量計(jì)算的結(jié)果作為屬性;
- 方法簡寫法能夠省略function關(guān)鍵字以及冒號:,讓方法的定義更加簡潔;
- 舍棄了重復(fù)屬性的檢查,讓后面的屬性覆蓋掉前面同名屬性的屬性值;
- 指定了數(shù)字類型鍵->字符串類型鍵->符號類型鍵的對象自有屬性的枚舉順序。
針對對象原型:
- Object.assign()方法能夠?qū)⒍鄠€(gè)提供者對象的屬性整合到接受者對象中,能夠方便實(shí)現(xiàn)對象的混入模式;
- Object.is()方法在處理特殊值時(shí)比嚴(yán)格比較符更加安全;
- Object.setPrototypeOf()方法能夠更加方便更改一個(gè)對象的原型;
- 提供super關(guān)鍵字,訪問原型上的方法。