對象的改變
ES6對象的變化不多,主要有以下幾點變化:
- 語法簡化和語法改變;
- 添加一些新的方法,Object.is(), Object.assign(), Object.setPrototypeOf();
- 引入super()
一.語法改變
1.語法簡化
ES6語法簡化主要是一下2個方面:
1.屬性初始化器 property initializer
// ES5-,返回的對象字面量對參數進行復制后賦值
function createPerson(name, age) {
return {
name: name,
age: age
};
}
ES6簡化這種寫法:當對象屬性名和局部變量名一樣時,可以省略冒號和值
// ES6
function createPerson(name, age) {
return {
name,
age
};
}
2.簡寫方法 concise methods
// ES5
var obj = {
name: "Nicholas",
sayName: function() {
console.log(this.name);
}
};
ES6可以省略冒號和function關鍵詞,簡寫語法的另一個用處就是可以調用super()方法,非簡寫語法則不能(后面會介紹super方法)
// ES6
var obj = {
name: "Nicholas",
sayName() {
console.log(this.name);
}
};
2.計算屬性名
變量可以作為對象字面量屬性:
let lastName = "last name";
let person = {
"first name": "Nicholas",
[lastName]: "Zakas" // 使用方括號將變量添加進去
};
person["first name"]; // "Nicholas"
person[lastName]; // "Zakas" 變量計算為字符串"last name"
// 另一種用法
var suffix = "name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
person("first name"); // "Nicholas"
person("last name"); // "Zakas"
3.語法修改
ES5 嚴格模式下不允許有重復屬性, 而ES6嚴格和非嚴格模式都允許有重復屬性
// ES5嚴格模式下, 下面情況拋出錯誤; ES6 則允許這種情況
"use strict;"
var obj = {
name: "Nicholas",
name: "James"
};
二.新方法
1.Object.is()
這個方法用于判斷一些嚴格等于以前不能判斷的等式,比如isNaN()判斷NaN不夠準確,+0,-0之間的問題。
// 我們知道NaN自身都不相等
NaN === NaN; // false
// 判斷NaN用isNaN方法,但是這個方法并不準確,undefined也會返回true,如:
isNaN(NaN); // true
isNaN(undefined); // true
// 可以自定義一個函數來判斷NaN
function isReallyNaN(o) {
if (typeof o === "number") {
return o !== o;
}
return false;
}
isReallyNaN(NaN); // true
isReallyNaN(undefined); // false
ES6方法
Object.is(NaN, NaN); // true
// 對于+0,-0 js引擎中兩者是不相等的,但是一般比較
+0 === -0; // true
Object.is(+0, -0); // false
2.Object.assign()
對象組合模式在js中很流行,一般我們稱之為mixins, 指的是將一個對象的屬性和方法賦給另一個對象。
ES5:
function mixin(receiver, supplier) {
Object.keys(supplier).forEach(
key => {receiver[key] = supplier[key]}
);
return receiver;
}
ES6 Object.assign()和上面的方法差不多,不過可以接受任意supplier
Object(receiver, supplier[, supplier...]);
// **supplier中若有重復屬性, 后面的屬性將重寫前面的屬性**
var receiver = {};
Object.assign(reveiver,
{
type: "js",
name: "file.js"
},
{
type: "css"
}
);
receiver.name; // "file.js"
receiver.type; // "css"
3.Object.setPrototypeOf()
ES6之前一個對象的原型在創建之后是不能改變的, ES6通過新方法setPrototypeOf()來修改一個對象的原型。
Object.setPrototypeOf(obj, protoObj);
// 通過修改對象內部[[prototype]]屬性
eg
let person = {
saySomething() {
return "hello";
}
};
let dog = {
saySomething() {
return "woof";
}
};
let friend = Object.create(person);
friend.saySomething(); // "hello"
Object.getPrototypeOf(friend) === person; // true
// 將原型改為dog
Object.setPrototypeOf(friend, dog);
friend.saySomething(); // "woof"
Object.getPrototypeOf(friend) === dog; // true
三.super
為訪問對象原型提供了很大的便利,在多級原型(即多級繼承)中及其有用,在多級繼承中Object.getPrototypeOf()有些條件下是不能使用的。
只能用于簡寫方法中(concise method)
let person = {
saySomething() {
return "hello";
}
};
let dog = {
saySomething() {
return "woof";
}
};
let friend = {
saySomething() {
return Object.getPrototypeOf(this).saySomething.call(this) + " hi";
}
};
Object.setPrototypeOf(friend, person);
friend.saySomething(); // "hello hi"
// 多級繼承
var rel = Object.create(friend); // rel 繼承 friend
**rel.saySomething(); // ERROR**
// 可以通過super簡寫上面friend對象
let friend = {
saySomething() {
return super.saySomething() + " hi";
}
};
// 多級繼承中
var rel = Object.create(friend); // rel 繼承 friend
rel.saySomething(); // OK "hello hi"
總結
總的來講,ES6對象上的改動不是很大,主要是新添加了一些方法,和語法上的優化,最重要的是對原來一些比較模糊的概念進行了正是規范,還有super方法的引入,對繼承的便利提供了很大的幫助。