深入理解ES6--4.擴(kuò)展的對象功能

原創(chuàng)文章&經(jīng)驗(yàn)總結(jié)&從校招到A廠一路陽光一路滄桑

詳情請戳www.codercc.com

image

主要知識點(diǎn)有對象類別、屬性速記法、方法簡寫、需計(jì)算屬性名、Object.is()方法、Object.assign()方法、可允許重復(fù)的屬性、自有屬性的枚舉順序、Object.setPrototypeOf()方法、super引用、方法定義

擴(kuò)展的對象功能.png

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ù)字類型鍵->字符串類型鍵->符號類型鍵的枚舉順序:

  1. 所有的數(shù)字類型鍵,按升序排列;
  2. 所有的字符串類型鍵,按被添加到對象的順序排列;
  3. 所有的符號類型,也按添加順序排列
//自有屬性的枚舉順序

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):

針對對象字面量:

  1. 速記法屬性能夠更加輕易的將作用域內(nèi)的變量值賦值給同名屬性;
  2. 需計(jì)算屬性名規(guī)則能夠更方便的將,變量、字符串字面量以及通過變量計(jì)算的結(jié)果作為屬性;
  3. 方法簡寫法能夠省略function關(guān)鍵字以及冒號:,讓方法的定義更加簡潔;
  4. 舍棄了重復(fù)屬性的檢查,讓后面的屬性覆蓋掉前面同名屬性的屬性值;
  5. 指定了數(shù)字類型鍵->字符串類型鍵->符號類型鍵的對象自有屬性的枚舉順序。

針對對象原型:

  1. Object.assign()方法能夠?qū)⒍鄠€(gè)提供者對象的屬性整合到接受者對象中,能夠方便實(shí)現(xiàn)對象的混入模式;
  2. Object.is()方法在處理特殊值時(shí)比嚴(yán)格比較符更加安全;
  3. Object.setPrototypeOf()方法能夠更加方便更改一個(gè)對象的原型;
  4. 提供super關(guān)鍵字,訪問原型上的方法。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容