ES6 对象的新增方法
<h3>对象的新增方法</h3>
<hr />
<ul>
<li><strong>Object.is(a,b)</strong>
用来比较两个值是否严格相等</li>
</ul>
<pre><code class="language-javascript">var obj = Object.is('foo','foo');
console.log(obj) //true</code></pre>
<ul>
<li><strong>Object.assign()</strong>
用于对象的合并,将源对象的所有可枚举属性,复制到目标对象
Object.assign方法的<strong>第一个参数是目标对象</strong>,后面的参数都是源对象。
注意:如果只有一个参数Object.assign()会直接返回该参数</li>
</ul>
<pre><code class="language-javascript">const target = {a:1};
const source1 = {b:2};
const source2 = {c:3};
Object.assign(target,source1,source2);
console.log(target) //{a: 1, b: 2, c: 3}
//只有一个参数的情况
const obj = {a: 1};
Object.assign(obj) === obj // true
//如果该参数不是对象,则会先转成对象,然后返回。
console.log(Object.assign(2)) //Object
//由于undefined 和 null无法转化为对象,所以他们作为参数就会报错
Object.assign(undefined) // 报错
Object.assign(null) // 报错
//如果undefined 和 null不在首参数,就不会报错,
//首先这些参数首先会转化为对象,不能转化就会跳过
let obj = {a: 1};
Object.assign(obj, undefined) === obj // true
Object.assign(obj, null) === obj // true
//其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错
//字符串会以数组的形式,拷贝入目标对象
const v1 = 'abc';
const v2 = true;
const v3 = 10;
const obj = Object.assign({}, v1, v2, v3);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
//下面代码中,布尔值、数值、字符串分别转成对应的包装对象,可以看到它们的原始值都在包装对象的内部属性[[PrimitiveValue]]上面,这个属性是不会被Object.assign拷贝的。只有字符串的包装对象,会产生可枚举的实义属性,那些属性则会被拷贝。
Object(true) // {[[PrimitiveValue]]: true}
Object(10) // {[[PrimitiveValue]]: 10}
Object('abc') // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
//(1)浅拷贝
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
//(2)同名属性的替换
const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)//// { a: { b: 'hello' } }
//(3)数组的处理
Object.assign可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5])// [4, 5, 3]
//(4)取值函数的处理
Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
const source = {
get foo() { return 1 }
};
const target = {};
Object.assign(target, source)// { foo: 1 }
//上面代码中,source对象的foo属性是一个取值函数,Object.assign不会复制这个取值函数,只会拿到值以后,将这个值复制过去。</code></pre>
<ul>
<li><strong>Object.keys() </strong>
ES5 引入了Object.keys方法,返回一个数组,
成员是参数对象自身的(不含继承的)
所有可遍历(enumerable)属性的键名。</li>
</ul>
<pre><code class="language-javascript">var obj = {foo:'bar',baz:'42'};
Object.keys(obj) //["foo","baz"]
ES2017 引入了跟Object.keys配套的Object.values和Object.entries,
作为遍历一个对象的补充手段,供for...of循环使用。
let {keys, values, entries} = Object;
let obj = { a: 1, b: 2, c: 3 };
for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}</code></pre>
<ul>
<li><strong>Object.values</strong>
Object.values方法返回一个数组,成员是参数对象自身的
(不含继承的)所有可遍历(enumerable)属性的<strong>键值</strong>。</li>
</ul>
<pre><code class="language-javascript">const obj ={foo:'bar',baz:42};
Object.values(obj)//['bar',42]
返回数组的成员顺序,与本章的《属性的遍历》部分介绍的排列规则一致。
const obj = { 100: 'a', 2: 'b', 7: 'c' };
Object.values(obj)
// ["b", "c", "a"]
上面代码中,属性名为数值的属性,是按照数值大小,
从小到大遍历的,因此返回的顺序是b、c、a。
**如果Object.values方法的参数是一个字符串,会返回各个字符组成的一个数组。**
Object.values('foo')// ['f', 'o', 'o']
2.将对象转换成真正的Map结构
const obj = { foo: 'bar', baz: 42 };
const map = new Map(Object.entries(obj));
map // Map { foo: "bar", baz: 42 }
</code></pre>
<ul>
<li><strong>Object.entries()</strong>
Object.entries()方法<strong>返回一个数组</strong>,成员是参数对象
自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组</li>
</ul>
<pre><code class="language-javascript">//例一(键值对象 => 键值数组)
const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]</code></pre>
<ul>
<li><strong>Object.fromEntries()</strong>
Object.fromEntries()方法是Object.entries()的逆操作,
用于将一个<strong>键值对数组转为对象</strong>。</li>
</ul>
<pre><code class="language-javascript">//例一(键值数组 => 对象)
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }
// 例二()
const map = new Map().set('foo', true).set('bar', false);
Object.fromEntries(map)
// { foo: true, bar: false }</code></pre>