1.Object.is()

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

就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false

不同之处只有两个:一是+0不等于-0,二是NaN等于自身。

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
+0 === -0 //true
NaN === NaN // false

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

 

2.Object.assign()

Object.assign

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

const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。

注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

常见用途

 (1)为对象添加属性

class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}

 (2)为对象添加方法

Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});

// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};

 (3)克隆对象


对于Object.assign()而言, 如果对象的属性值为简单类型(string, number),通过Object.assign({},srcObj);得到的新对象为‘深拷贝

如果属性值为对象或其它引用类型,那对于这个对象而言其实是浅拷贝的


function clone(origin) {
return Object.assign({}, origin);
}
function clone(origin) {
return Object.assign({}, origin);
}

 (4)合并多个对象

const merge =
(target, ...sources) => Object.assign(target, ...sources);
const merge =
(target, ...sources) => Object.assign(target, ...sources);

如果希望合并后返回一个新对象,可以改写上面函数,对一个空对象合并

const merge =
(...sources) => Object.assign({}, ...sources);
const merge =
(...sources) => Object.assign({}, ...sources);

 (5)为属性指定默认值

const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
options = Object.assign({}, DEFAULTS, options);
console.log(options);
 // ...
}
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
options = Object.assign({}, DEFAULTS, options);
console.log(options);
 // ...
}

 

3. Object.setPrototypeOf()和Object.getPrototypeOf()

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

let proto = {};
let obj = { x: 10 };
Object.setPrototypeOf(obj, proto);
proto.y = 20;
proto.z = 40;
obj.x // 10
obj.y // 20
obj.z // 40
let proto = {};
let obj = { x: 10 };
Object.setPrototypeOf(obj, proto);
proto.y = 20;
proto.z = 40;
obj.x // 10
obj.y // 20
obj.z // 40

Object.getPrototypeOf,用于读取一个对象的原型对象。

function Rectangle() {
 // ...
}
const rec = new Rectangle();
Object.getPrototypeOf(rec) === Rectangle.prototype
// true

Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype
// false
function Rectangle() {
 // ...
}
const rec = new Rectangle();
Object.getPrototypeOf(rec) === Rectangle.prototype
// true

Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype
// false

 

4.Object.keys(), Object.values()和Object.entries()

var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]

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]
 
  

    }

 

5.Object.fromEntries()

Object.fromEntries()

方法是 Object.entries()

的逆操作,用于将一个键值对数组转为对象。

Object.fromEntries([
  ['foo', 'bar'],
  ['baz', 42]
])
// { foo: "bar", baz: 42 }
Object.fromEntries([
  ['foo', 'bar'],
  ['baz', 42]
])
// { foo: "bar", baz: 42 }