在ES6中,对象身上也有一些变化,另外也新增了一些方法,一起来梳理一下
首先
1. ES6支持对象的简洁语法
let obj = {
name: name,
age: age,
show: function () {//code...}
}
以上代码可以简写成
let obj = {
name,
age,
show() {//code...}
}
对象简洁语法可总结为一下两点规则:
(1)属性名和属性值一致时,可以简写成一个;
(2)对象中的函数由原来格式 函数名 : function(形参列表){代码块},变成 函数名(形参列表){代码块};即省略了:function
- 在定义字面量对象时,属性名可以使用表达式了,表达式用方括号[]括起来,放在属性名位置
const prop = 'aaa';
const obj = {
[prop + 'bbb']: 1,
[prop + 'fn']() {
console.log(arguments.callee.name);
}
}
obj[prop + 'fn']();//aaafn
obj.aaafn();//aaafn
console.log(obj[prop+'bbb']);//1
console.log(obj.aaabbb);//1
- 对象身上新增了Object.is()方法
Object.is方法用于优化===的两个问题:
NaN不等于NaN、+0等于-o的问题
console.log(NaN === NaN);//false
console.log(+0 === -0);//true
//========================================//
console.log(Object.is(NaN,NaN));//true
console.log(Object.is(+0,-0));//false
下面手动封装一下is方法
Object._is = function (one, two) {
if (Number.isNaN(one) && Number.isNaN(two)) {
return true;
}
if (one === 0 && two === 0) {
if (1 / one < 0 && 1/two >0){
return false
}
if (1 / one > 0 && 1/two <0) {
return false
}
}
return one === two;
}
console.log(Object._is(NaN,NaN));//true
console.log(Object._is(+0, -0));//false
console.log(Object._is(-0, +0));//false
这里有个小窍门,就是判断一个数是+0还是-0,正常是比较难判断的,因为他们都全等于0,但是我可以利用一个正数除以+0为Infinity,除以-0为-Infinity的规律,在通过Infinity和-Infinity分别跟0比较,判断出是-0还是+0
- 对象身上新增了Object.assign()方法
assign用于把多个对象合并到到一个对象上,第一个参数是要把其他对象合并到的对象,剩下其他参数是要被合并的对象
const a = { name: 'a', funA() { } }
const b = { name: 'b', funB() { } }
const c = { name: 'c', funC() { } }
const d = { name: 'd', funD() { } }
const obj = Object.assign(a,b,c,d);
console.log(a,b,c,d)
console.log(obj)
console.log(a === obj)
结果
可以看出几个结论:
(1)通过assign合并对象,属性名重复,后面的属性值会覆盖前面相同属性名的属性值
(2)执行结果返回的就是合并了其他对象的第一个参数对象
所以可以利用assign来拷贝一个对象
const a = { name: 'a', funA() { } }
const b = Object.assign({},a);
b.name = 'b';
console.log(`a.name为:${a.name}; b.name为:${b.name}`)
//a.name为:a; b.name为:b
手动封装如下
Object._assign = function () {
if (arguments.length == 0) {
throw new TypeError(`Cannot convert undefined or null to object`);
}
if (arguments.length == 1) {
return arguments[0];
}
if (arguments.length >= 2) {
let target = arguments[0];
for (let i = 1; i < arguments.length; i++) {
// 拿出每一个要被合并的对象,判断对象里面属性,在arguments[0]中是否已经存在,没有存在则加入,有存在就覆盖。
for(let key in arguments[i]){
//key表示每个要合并的对象的属性,直接添加到target中去就可以,有就覆盖,没有就添加
target[key] = arguments[i][key];
}
}
return target
}
}
let obj1 = { name: 'a' };
let obj2 = { name: 'b' }
console.log(Object._assign(obj1, obj2));
- 对象身上新增了Object.create方法
Object.create()用于产生指定原型的新对象,第一个参数可以是某对象或者null,如果传入null表示该对象没有原型。
const obj = Object.create(null);
console.log(obj)
里面没有__proto__指向原型
- 对象身上新增Object.getPrototypeOf()和Object.setPrototypeOf()用于获取和设置对象的原型属性
__proto__
Object.setPrototypeOf(target, { a: 'alice'})
Object.getPrototypeOf(target) //{ a: 'alice', __proto__: Object}
猜测底层实现应该不是用__proto__
吧,因为他们出现的原因就是,为了避免直接操作私有属性__proto__
,如果底层用它,那跟我直接使用修改__proto__
有啥区别,那就没有意义。
- 对象身上新增Object.getOwnPropertyDescriptors()用于获取某对象的各个属性的详细信息,包括value,writable,enumerable,configurable等,返回新对象。
let obj = {a:1,b:2,c:3};
console.log(Object.getOwnPropertyDescriptors(obj))
注意:上面Object.create()的第二个参数就是这种Object.getOwnPropertyDescriptors()所返回的格式
let obj = {a:1,b:2,c:3};
let newObj = Object.create(null,Object.getOwnPropertyDescriptors(obj));
console.log(newObj)//{a: 1, b: 2, c: 3}
console.log(obj === newObj)//false
我们发现其实可以通过Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj))来拷贝一个对象
- ES2017在对象身上还新增了Object.keys()、Object.values、Object.entries
Object.keys() 用于返回由对象的key组成的数组
Object.values 返回由对象的value组成的数组
Object.entries 返回由多个key和value组成的键值对的数组
let obj = {a:1,b:2,c:3};
console.log(Object.keys(obj));//["a", "b", "c"]
console.log(Object.values(obj));//[1, 2, 3]
console.log(Object.entries(obj));//[["a", 1], ["b", 2], ["c", 3]]
要手动封装,也是跟切菜一样简单
(1)keys实现
Object._keys = function(o){
let res = [];
for(let key in o){
res.push(key)
}
return res;
}
console.log(Object._keys(obj));//["a", "b", "c"]
(2)values实现
Object._values = function(o){
let res = [];
for(let key in o){
res.push(o[key]);
}
return res;
}
let obj = {a:1,b:2,c:3};
console.log(Object._values(obj));//[1, 2, 3]
(2)手动实现entries
Object._entries = function(o){
let res = [];
for(let key in o){
res.push([key,o[key]]);
}
return res;
}
let obj = {a:1,b:2,c:3};
console.log(Object._entries(obj));//[["a", 1], ["b", 2], ["c", 3]]
以上就是ES6在对象身上新增的所有东西
网友评论