ES6-Object新增的API&声明对象的简写&对象函数的简写

以下是对新增的API,声明对象的简写,对象函数的简写,对象拓展运算符的学习


新增的API

ES6给Object扩展了许多新的方法,如:

-keys(obj),获取对象的所有key形成的数组

-values(obj),获取对象的所有value形成的数组

-entries(obj),获取对象的所有key和value形成的二维数组

1
2
3
4
5
6
7
8
9
const person = {
name: 'jack',
age: 21,
language: ['java', 'js', 'css'],
};
console.log(Object.keys(person));
console.log(Object.values(person));
console.log(Object.entries(person));

Object
对象的新方法

Object.assign(dest, ···src) ,将多个src对象的值拷贝到dest中(第一层为深拷贝,第二层为浅拷贝)

用于将源对象的所有可枚举属性复制到目标对象中。

1
2
3
4
5
6
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
// Object.assign方法的第一个参数是目标对象,后面的参数都是源对象
Object.assign(target, source1, source2);
console.log(target); //{a: 1, b: 2, c: 3}

Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
如果只有一个参数,Object.assign()会直接返回该参数。
如果该参数不是对象,则会先转成对象,然后返回。
由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。

Object.is()

ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

1
2
3
4
5
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false

Object.getOwnPropertyDescriptors()

ES5 的Object.getOwnPropertyDescriptor()方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的描述对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const obj = {
foo: 123,
get bar() { return 'abc' }
};

Object.getOwnPropertyDescriptors(obj)
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: get bar],
// set: undefined,
// enumerable: true,
// configurable: true } }

上面代码中,Object.getOwnPropertyDescriptors()方法返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的描述对象。

__proto__属性

JavaScript 语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。
__proto__属性
__proto__属性(前后各两个下划线),用来读取或设置当前对象的原型对象(prototype)。目前,所有浏览器(包括 IE11)都部署了这个属性。

1
2
3
4
5
6
7
8
9
// es5 的写法
const obj = {
method: function() { ... }
};
obj.__proto__ = someOtherObj;

// es6 的写法
var obj = Object.create(someOtherObj);
obj.method = function() { ... };

该属性没有写入 ES6 的正文,而是写入了附录,原因是__proto__前后的双下划线,说明它本质上是一个内部属性,而不是一个正式的对外的 API,只是由于浏览器广泛支持,才被加入了 ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。

参考文章

es6对象新增的方法

声明对象的简写

1
2
3
4
5
6
const age = 23;
const name = '张三';
const person1 = { age: age, name: name };

const person2 = { age, name };
console.log(person2);

对象函数的简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let person3 = {
name: 'jack',
//以前
eat: function (food) {
console.log(this.name + '在吃' + food);
},
//箭头函数this不能使用,对象,属性
eat2: (food) => console.log(person3.name + '在吃' + food),
//方法三 使用较多
eat3(food) {
console.log(this.name + '在吃' + food);
},
};
person3.eat('香蕉');
person3.eat2('苹果');
person3.eat3('橘子');

对象拓展运算符

  1. 拷贝对象(第一层为深拷贝,第二层为浅拷贝)
1
2
3
let p1 = { name: 'Amy', age: 15 };
let someone = { ...p1 };
console.log(someone); //age: 15 name: "Amy"
  1. 合并对象
1
2
3
4
5
6
let age1 = { age: 15 };
let name1 = { name: 'Amy' };
//假设之前已经有一个值,但是打印时最后的值还是会覆盖原来的值
let p2 = { name: 'zhangsan' };
p2 = { ...age1, ...name1 };
console.log(p2); //age: 15 name: "Amy"

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!