ES6对象的扩展

## Object.is()

 

ES5比较两个值是否相等:相等运算符(`==`)和严格相等运算符(`===`)。前者会自动转换数据类型,后者的`NaN`不等于自身,以及`+0`等于`-0`。`Object.is`一是`+0`不等于`-0`,二是`NaN`等于自身。

 

```js

Object.is('foo', 'foo') // true

Object.is({}, {}) // false

 

+0 === -0 //true

NaN === NaN // false

 

Object.is(+0, -0) // false

Object.is(NaN, NaN) // true

```

 

 

 

## Object.assign()

 

`Object.assign`方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

 

```js

var target = { a: 1, b: 1 };

 

var source1 = { b: 2, c: 2 };

var source2 = { c: 3 };

 

Object.assign(target, source1, source2);

console.log(target) // {a:1, b:2, c:3}

 

//如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性,只有一个参数,直接返回该参数。

```

 

由于`undefined`和`null`无法转成对象,所以如果它们作为参数,就会报错。

 

```

Object.assign(undefined) // 报错

Object.assign(null) // 报错

```

 

**注意:**`Object.assign`方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

 

```js

var obj1 = {a: {b: 1}};

var obj2 = Object.assign({}, obj1);

 

obj1.a.b = 2;

obj2.a.b // 2

```

 

对于这种嵌套的对象,一旦遇到同名属性,`Object.assign`的处理方法是替换,而不是添加。

 

**Lodash的`_.defaultsDeep`方法**,可以解决浅拷贝的问题,得到深拷贝的合并。

 

```js

var target = { a: { b: 'c', d: 'e' } }

var source = { a: { b: 'hello' } }

Object.assign(target, source)

// { a: { b: 'hello' } }

```

 

 

 

## Object.keys()

 

返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键名。

 

```js

var obj = { foo: "bar", baz: 42 };

Object.keys(obj)

// ["foo", "baz"]

```

 

 

 

## Object.values()

 

`Object.values`方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值。

 

```js

var obj = { foo: "bar", baz: 42 };

Object.values(obj)

// ["bar", 42]

```

 

```js

var obj = { 100: 'a', 2: 'b', 7: 'c' };

Object.values(obj)

// ["b", "c", "a"],

//返回数组的成员顺序,与《属性的遍历》部分介绍的排列规则一致。

```

 

 

 

## Object.entries

 

`Object.entries`方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。

 

```js

var obj = { foo: 'bar', baz: 42 };

Object.entries(obj)

// [ ["foo", "bar"], ["baz", 42] ]

```

 

`Object.entries`方法的一个用处是,将对象转为真正的`Map`结构。

 

```js

var obj = { foo: 'bar', baz: 42 };

var map = new Map(Object.entries(obj));

console.log(map) // Map { foo: "bar", baz: 42 }

```

 

 

 

## 属性名表达式

 

```js

var lastWord = 'last word';

 

var a = {

  'first word': 'hello',

  [lastWord]: 'world'

};

 

a['first word'] // "hello"

a[lastWord] // "world"

a['last word'] // "world"

```

 

 

 

## 属性的遍历

 

ES6一共有5种方法可以遍历对象的属性。

 

**(1)for...in**

 

`for...in`循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。

 

**(2)Object.keys(obj)**

 

`Object.keys`返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。

 

**(3)Object.getOwnPropertyNames(obj)**

 

`Object.getOwnPropertyNames`返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。

 

**(4)Object.getOwnPropertySymbols(obj)**

 

`Object.getOwnPropertySymbols`返回一个数组,包含对象自身的所有Symbol属性。

 

**(5)Reflect.ownKeys(obj)**

 

`Reflect.ownKeys`返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。

 

**以上的5种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。**

 

- 首先遍历所有属性名为数值的属性,按照数字排序。

- 其次遍历所有属性名为字符串的属性,按照生成时间排序。

- 最后遍历所有属性名为Symbol值的属性,按照生成时间排序。

 

 

 

## 对象的扩展运算符

 

**Rest解构赋值**

 

```js

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };

console.log(x) // 1

console.log(y) // 2

console.log(z) // { a: 3, b: 4 }

```

 

```

let { x, y, ...z } = null; // 运行时错误

let { x, y, ...z } = undefined; // 运行时错误

```

 

```

let { ...x, y, z } = obj; // 句法错误

let { x, ...y, ...z } = obj; // 句法错误

```

 

**注意:**Rest解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么Rest解构赋值拷贝的是这个值的引用,而不是这个值的副本。

 

```js

let obj = { a: { b: 1 } };

let { ...x } = obj;

obj.a.b = 2;

x.a.b // 2

```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值