对象的改变
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方法的引入,对继承的便利提供了很大的帮助。