对象的扩展
语法做出的调整
1、对重复定义的属性新增了一个检查,取最后的属性为实际值
var obj1 = {
name: "digua",
name: "tudou"
} // 实际值为tudou,这种写法在es5中会报错
2、规定对象属性的枚举顺序,主要体现在Object.getOwnPropertyNames和Reflect.ownKeys方法上。
枚举顺序如下:
(1)所有数字类型键按升序排列(2)字符串类型,按被添加到对象顺序(3)符号类型键,按添加到对象顺序。
对象定义属性的扩展
1、创建对象时有了更简洁的方法
在ES5种对象定义表达方法必须为键值对的组合,那么在一些情况下对象在初始化时会有重复
//ES5
function createJson (name, age) {
return {
name: name,
age: age
}
}
以上代码在ES6中有更简单的写法
//ES6
function createJson (name, name) {
return {
name,
age
}
}
//当对面字面量只有名称时,js引擎会在作用域内寻找同名变量并赋予这个属性
ES6中对象方法也得到了简化
//es5
var person = {
name: 'demo',
dosomething: function () { console.log(this.name) }
}
//es6
let person = {
name: 'demo',
dosomething() { console.log(this.name) }
}
2、扩展了“【】”定义和访问对象属性的功能,可以支持动态属性名如例
// es6
let first = "name"
let person = {
[first + ' a']: 'digua',
[first + ' b']: 'tudou'
}
console.log(person) // person: {"name a": "digua", "name b": "tudou"}
console.log(person[first + ' a']) // digua
Object对象的新增方法
1、Object.is(param1,param2)方法,用来比较来个传入参数是否相等,弥补了“===”全等比较的一些不足,多数情况下和全等比较结果相同。
// ===号比较
console.log(5 === "5") // false
console.log(+0 === -0) // true
console.log(NaN === NaN) // false
// Object.is()
Object.is(5, "5") // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
2、Obeject.assign()方法
这个方法用来做源对象到目标对象的浅复制(浅拷贝),即注意拷贝的源对象属性为一个对象时复制的是它的引用。源对象的对象属性的任何变化,都会反映到目标对象上面,反之亦然。如例
let obj1 = { name: "digua", person: { name: "tudou" } }
let obj2 = { age: "100" }
Object.assign(obj2, obj1)
obj2.name // digua
obj2.person.name = "coco"
obj1.person.name // coco 这里因为obj2调用了它的引用将其中的属性改掉了
3、Object.getPrototypeof()方法
此方法可以修改任意指定对象的原型。例如
let person = {
sayName() {
return "digua"
}
}
let dog = {
sayName() {
return "kk"
}
}
let friend = Object.create(person)
console.log(friend.sayName()) // digua
console.log(Object.getPrototypeOf(friend) === person) //true
//使用setPrototypeOf更改原型
Object.setPrototypeOf(friend, dog)
console.log(friend.sayName()) // kk
console.log(Object.getPrototypeOf(friend) === dog) //true
使用super()来调用原型上的方法
用super()所调用的方法会被设置好其内部的this 绑定,以自动使用该 this 值来进行工作。这比这ES5中用Object.getPrototypeOf()和call()结合使用来调用原型上方法更简便,也省去了一些可能出现的错误。例如
// es5
let person = {
sayname() {
return "Hello";
}
};
// 原型为 person
let friend = {
sayname() {
return Object.getPrototypeOf(this).sayname.call(this) + ", hi!";
}
};
Object.setPrototypeOf(friend, person);
// 原型为 friend
let relative = Object.create(friend);
console.log(person.sayname()); // "Hello"
console.log(friend.sayname()); // "Hello, hi!"
console.log(relative.sayname()); // error!
//因为relative调用方法时this指向的还是friend所以导致的循环调用从而报错
//es6 将 friend内sayname用super改写 就不会有问题,因为内部的this指向是固定指向person的
let friend = {
sayname() {
return super.sayname() + ", hi!";
}
};
新加入了[[HomeObject]]函数内部属性
如果一个函数拥有内部属性[[HomeObject]]则该函数被归为一个方法。
let person = {
sayname() {
console.log('digua')
}
}
// 这时候person.sayname 为 [[HomeObject]]属性为person