深入理解ES6--4.擴充套件的物件功能

你聽___發表於2018-04-22

深入理解ES6--4.擴充套件的物件功能

主要知識點有物件類別、屬性速記法、方法簡寫、需計算屬性名、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規定了自有屬性的列舉順序,會依次按照數字型別鍵->字串型別鍵->符號型別鍵的列舉順序:

  1. 所有的數字型別鍵,按升序排列;

  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. 更強大的原型

修改物件原型

在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更加簡單易用和更加強大,在物件功能上具體有這樣一些改進:

針對物件字面量:

  1. 速記法屬效能夠更加輕易的將作用域內的變數值賦值給同名屬性;
  2. 需計算屬性名規則能夠更方便的將,變數、字串字面量以及通過變數計算的結果作為屬性;
  3. 方法簡寫法能夠省略function關鍵字以及冒號:,讓方法的定義更加簡潔;
  4. 捨棄了重複屬性的檢查,讓後面的屬性覆蓋掉前面同名屬性的屬性值;
  5. 指定了數字型別鍵->字串型別鍵->符號型別鍵的物件自有屬性的列舉順序。

針對物件原型:

  1. Object.assign()方法能夠將多個提供者物件的屬性整合到接受者物件中,能夠方便實現物件的混入模式;
  2. Object.is()方法在處理特殊值時比嚴格比較符更加安全;
  3. Object.setPrototypeOf()方法能夠更加方便更改一個物件的原型;
  4. 提供super關鍵字,訪問原型上的方法。

相關文章