首先,在JavaScript中对象是个很重要的概念,因为在JavaScript中一切都是对象,无论是函数,还是数组。同样,ES6这次也带来了一些新特性。能够帮助我们更加轻松与准确的完成想要完成的目标。
对象字面量语法拓展
对象字面量属性简写
在ES6之前。我们使用字面量创建属性,会写一个属性名,后面跟一个":",最后跟着属性值。看起来一切都是很简洁的,但是在属性值与属性名同名时,这就很痛苦了,每次都要写两个同样的文字。我们看个例子:
let Person = function(name,age){
return {
name : name,
age : age,
}
}
复制代码
一个两个这种代码没问题,但是当类似的代码量一旦多起来,那便是很痛苦的一件事了。但是,在ES5中,这个问题将得到解决。它为我们提供了简写方式。
let Person = function(name,age){
return {
name,
age,
}
}
复制代码
在使用字面量的时候,我们只需写一个变量名就好,剩下的工作由JavaScript引擎帮我们去做。JavaScript引擎回去可访问作用域查找同名属性,找到便会将该变量的值赋值给字面量对象的同名属性。如果没找到,这个属性的值为undefined。
对象字面量的可计算属性名
在ES6之前,我们可以在对象创建之后,使用可计算属性名,但是无法在对象字面量中使用可计算属性名。现在ES6将可计算属性名带到了对象字面量中。
// ES6之前
let param1 = 'name';
let person = {};
person[param1] = 'kidd';
console.log(person[name]); // kidd
//不允许
let dog = {
[param]:'Snoopy',
}
// ES6
let firstName = 'first Name';
let cat = {
[firsName]:'tom'
}
console.log(cat[firstName]); // tom
复制代码
对象方法的简写
这不是一个重大的改进。但是能帮助我们书写起来更容易。
// ES6之前按
let person= {
getName:function(){
return : this.name
}
}
// ES6
let person = {
getName(){
return this.name;
}
}
复制代码
重复的对象字面量属性
在ES5及之前,我们如果在对象字面量中声明了两个同名属性,严格模式下便会报错。而ES6中将这个特性改变了,无论是否在严格模式下,对象字面量中声明了两个同名属性,之后后面的属性会生效。
let person = {
getName(){
return 'tom';
},
getName(){
return 'jure';
}
}
person.getName(); // jure
复制代码
对象自有属性的枚举顺序
在ES6之前自由属性的枚举顺序基本都是百家争鸣,不同的JavaScript引擎,都会有不同的枚举顺序,这次ES6算是将自由属性的枚举顺序给出了官方说法
- 所有数字键按照升序排列
- 所有字符串键按照它们被加入对象的顺序排列
- 所有symbol键按照它们被加入对象的顺序排列
对象新增方法
在ES6也给对象新增了一些方法,下面让我们来看看
Object.is()
Object.is()很想一个完整版的 “===”,因为它大部分情况下与 “===” 相同,只有两种情况与 “===” 有一些差别。就是下面两种情况
console.log(-0 === +0); //true
console.log(Object.is(+0,-0)); //false
console.log(NaN === NaN); //false
console.log(NaN,NaN); //true
复制代码
除了上面两种情况,与 “===”是一样的。
Object.assign()
因为很多JavaScript第三方库有混合模式,这次ES6便将它们直接引入进来。assign方法的主要作用是将一个对象的方法、属性复制给另一个对象。注意,这里的复制其实是浅复制,如果被复制对象的属性值是一个对象的话,那么便只是将这个对象的引用复制给被复制对象。
function EventTarget(){ doSomething };
EventTarget.prototype = {
constructor : EventTarget,
emit : function(){ doSomething },
on : function(){ doSomething }
}
var obj = {},
Object.assign(obj,EventTarget.prototype);
obj.on();
复制代码
这样的话,新创建的对象就会拥有之前对象的属性。而且assign是可以接受任意数量的源对象的。如果不同的源对象中有同名属性,最后被复制对象中会采用最有一个拥有此属性的对象的属性值。 还有一个很重要的点。assign是不能复制访问器属性的。如果源对象中有访问器属性,会在新的对象中变为数值属性。
增强对象原型
我们都知道,JavaScript最特别的地方就是使用了原型继承的方式。而现在,ES6对对象原型又进行了增强。
Super引用
super引用其实就是保存了当前对象的原型对象的引用,在ES6之前,我们要获得对象的原型只有通过Object.getPrototypeOf(this)的方法去返回原型对象。但是这个方法在某些情况的时候会发生某些错误,比如
let person = {
getGreeting(){
return 'Hello';
}
};
let friend = {
getGreeting(){
return Object.getPrototypeOf(this).getGreeting.call(this) + ", Hi!";
}
}
Object.setPrototypeOf(friend,person);
let relative = Object.create(friend);
console.log(person.getGreeting()); // Hello
console.log(friend.getGreeting()); // Hello, Hi!
console.log(relative.getGreeting()); // error
复制代码
这里的问题是陷入了一个调用死循环,this是relative时Object.getPrototypeOf(this)返回的对象是friend。而Object.getPrototypeOf(this).getGreeting会调用friend的getGreeting()方法。后面的call(this)又会去改变当前的函数作用域,因此,陷入了一个递归调用的死循环,最后栈溢出报错,但是在ES6中使用super就会解决这个问题
let person = {
getGreeting(){
return 'Hello';
}
};
let friend = {
getGreeting(){
return super.getGreeting() + ", Hi!";
}
}
Object.setPrototypeOf(friend,person);
let relative = Object.create(friend);
console.log(person.getGreeting()); // Hello
console.log(friend.getGreeting()); // Hello, Hi!
console.log(relative.getGreeting()); // Hello, Hi!
复制代码
这是因为super引用不是动态变化的,它总是指向正确的对象。
改变对象原型的方法
在ES6之前我们要改变对象的原型很麻烦,现在ES6有了setPrototypeOf(),可以轻而易举的改变对象的原型。
let person = {
getGreeting(){
return 'Hello';
}
};
let dog = {
getGreeting(){
return 'Woof';
}
};
let friend = Object.create(person);
console.log(friend.getGreeting()); // Hello
console.log(Object,getPrototypeOf(friend) === person); //true
Object.setPrototype(friend,dog);
console.log(friend.getGreeting()); // Woof
console.log(Object,getPrototypeOf(friend) === dog); //true
复制代码
以上便是ES6有关对象的内容,如果您有不同的见解或者是本文哪里有错误,你都可以在下面留言给我!!!