主要知識點有物件類別、屬性速記法、方法簡寫、需計算屬性名、Object.is()方法、Object.assign()方法、可允許重複的屬性、自有屬性的列舉順序、Object.setPrototypeOf()方法、super引用、方法定義
1. 物件類別
物件有以下幾種類別:
- 普通物件:擁有JS物件所有預設的內部行為;
- 奇異物件:其內部行為在某些方面有別於預設行為;
- 標準物件:在ES6中被定義的物件,例如Array,Date等;
- 內建物件:在指令碼開始執行的時候由JS執行環境提供的物件,所有的標準物件都是內建物件
2. 物件字面量語法的擴充套件
屬性初始化的速記法
屬性初始化器的速記法可以用來消除屬性名和本地變數的重複情況,可以使用作用域內的變數值賦值給同名屬性:
function createPerson(name,age){
return {
name:name,
age:age
}
}
//由於屬性名和本地變數名相同,可以採用
//屬性初始化器的速記法,等價於
function createPerson(name,age){
return {
name,
age
}
}
複製程式碼
方法簡寫
在物件字面量的寫法中,為一個物件新增一個方法,需要指定物件的屬性以及具體的函式宣告。ES6提供了一種方法簡寫語法,通過省略function關鍵字,能夠讓為物件新增方法的語法更加簡潔。有一個重要的區別是:方法簡寫能夠使用super
,而非簡寫的方法不能使用super
。
//方法簡寫法
let person = {
sayName:function(){
return name;
}
}
//等價於
let person = {
sayName(){
return name;
}
}
複製程式碼
需計算屬性名
需計算屬性名規則允許物件字面量中屬性名是變數、字串字面量或者由變數計算而得的,具體寫法是通過方括號[]包含屬性名。
//需計算屬性名
let person = {};
let firstName = 'first name';
let suffix = '@github.com'
let email = 'email';
//變數
person[firstName] = 'hello';
//字串字面量
person['last name']= 'world';
//變數計算而得到的
person[email+suffix] = 'example@github.com'
複製程式碼
Object.is()
JS中比較兩個值是否相同的時候會使用嚴格等於運算子===
,但是,使用嚴格運算子式,+0和-0會認為這兩者是相等的,而NaN===NaN
是不相等的,使用Object.is()方法來判斷這兩者情況與使用嚴格相等符會有所不同,其他情況和使用嚴格相等運算子基本一致;
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()
一個物件從另外一個物件獲取屬性和方法,這是典型的混入(Mixin)模式,Object.assign()方法可以更簡潔的實現物件混入,該方法需要一個接受者物件和若干個供應者物件。接收者會按照供應者在引數中的順序來依次接收它們的屬性,這意味著,第二個供應者可能會覆蓋第一個供應者相同的屬性;
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()方法並未在接受者上建立訪問器屬性,即使供應者擁有訪問器屬性,由於Object.assign()方法使用賦值運算子,供應者的訪問器屬性會轉換成接受者的資料屬性;
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
複製程式碼
允許重複的屬性
在ES5嚴格模式下,為物件字面量中屬性會檢查是否重複,如果重複的話就會丟擲一個錯誤。而在ES6中,無論是在嚴格模式下還是非嚴格模式下,都不再檢查屬性是否重複,當屬性重複的時候,後面的屬性會覆蓋前面的屬性;
//重複的屬性
let person = {
name:'hello',
name:'world'
}
console.log(person.name); //world
複製程式碼
自有屬性的列舉順序
ES6規定了自有屬性的列舉順序,會依次按照數字型別鍵->字串型別鍵->符號型別鍵的列舉順序:
-
所有的數字型別鍵,按升序排列;
-
所有的字串型別鍵,按被新增到物件的順序排列;
-
所有的符號型別,也按新增順序排列
//自有屬性的列舉順序
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. 更強大的原型
修改物件原型
在ES6中可以通過Object.setPrototypeOF()方法修改物件的原型,該方法包含了兩個引數:一個是被修改原型的物件,一個是將被指定的原型;
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引用的話,只能在方法簡寫中才能使用,否則就會報錯:
let dog ={
getNanem:function (){
return super.getName()+' world';
}
}
報錯:Uncaught SyntaxError: 'super' keyword unexpected here
複製程式碼
方法定義
在ES6之前,方法的概念從未被正式定義,而在ES6中做出了正式定義:方法是擁有一個[[HomeObject]]內部屬性的函式,此內部屬性指向該方法所屬的物件;
//方法
let person = {
getName(){
return 'hello';
}
}
//不是方法
function getName(){
return 'hello world';
}
複製程式碼
4. 總結
ES6通過對物件功能的擴充套件,讓ES6更加簡單易用和更加強大,在物件功能上具體有這樣一些改進:
針對物件字面量:
- 速記法屬效能夠更加輕易的將作用域內的變數值賦值給同名屬性;
- 需計算屬性名規則能夠更方便的將,變數、字串字面量以及通過變數計算的結果作為屬性;
- 方法簡寫法能夠省略function關鍵字以及冒號:,讓方法的定義更加簡潔;
- 捨棄了重複屬性的檢查,讓後面的屬性覆蓋掉前面同名屬性的屬性值;
- 指定了數字型別鍵->字串型別鍵->符號型別鍵的物件自有屬性的列舉順序。
針對物件原型:
- Object.assign()方法能夠將多個提供者物件的屬性整合到接受者物件中,能夠方便實現物件的混入模式;
- Object.is()方法在處理特殊值時比嚴格比較符更加安全;
- Object.setPrototypeOf()方法能夠更加方便更改一個物件的原型;
- 提供super關鍵字,訪問原型上的方法。