对象的新增方法

Object.assign() 

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

参数1:目标对象,后面的参数都是源对象。

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 target = { a: 1 };

const source1 = { a: 2, b: 3 };
const source2 = { b: 4, c: 5 };

Object.assign(target, source1, source2);
console.log(target); // {a:2, b:4, c:5}

如果只有一个参数,Object.assign()会直接返回该参数。

const obj = {
    a: 1
};
Object.assign(obj) === obj // true
console.log(Object.assign(obj)); // { a: 1 }
Object.assign(obj).a = 2; 
console.log(obj); // { a: 2 }  // 注意:引用值拷贝的是地址

Object.assign()拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。

浅拷贝

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

const obj1 = {a: {b: 1}};
const obj2 = Object.assign({}, obj1);

obj1.a.b = 2;
obj2.a.b // 2

同名属性的替换(覆盖)

const target = { a: { b: 'c', d: 'e' } }
const source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }

Object.assign() 常见用途

为对象添加属性

class Point {
    constructor(x, y) {
        Object.assign(this, {
            x,
            y
        });
    }
}
let p = new Point(2, 3);
console.log(p.x); // 2
console.log(p.y); // 3

上面方法通过Object.assign()方法,将x属性和y属性添加到Point类的对象实例。

为对象添加方法

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

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

克隆对象(浅拷贝) 

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

克隆对象(深拷贝) 

function clone(origin) {
  let originProto = Object.getPrototypeOf(origin);
  return Object.assign(Object.create(originProto), origin);
}

合并多个对象

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

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

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

得到新对象例子

const a = {a:1};
const b = {b:2};
const c = {c:3};
const merge = (...sources) => Object.assign({}, ...sources);
var result = merge(a,b,c);
console.log(result); // { a: 1, b: 2, c: 3 }

Object.setPrototypeOf()

JavaScript 语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。

Object.setPrototypeOf方法的作用与__proto__相同,用来设置一个对象的原型对象(prototype),返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。

 

// 格式
Object.setPrototypeOf(object, prototype)

// 用法
const o = Object.setPrototypeOf({}, null);

 

const foo = {
    a: 1
};
const obj = {
    b: 2
};

// 返回它自己本身
var result = Object.setPrototypeOf(obj, foo);
console.log(result); // { b: 2 }  
console.log(result.__proto__); // { a: 1 }

该方法等同于下面的函数。

function setPrototypeOf(obj, proto) {
  obj.__proto__ = proto;
  return obj;
}

下面是一个例子。

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

上面代码将proto对象设为obj对象的原型,所以从obj对象可以读取proto对象的属性。

Object.getPrototypeOf()

该方法与Object.setPrototypeOf方法配套,用于读取一个对象的原型对象。

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

var result = Object.getPrototypeOf(obj);
console.log(result); // { y: 20, z: 40 }

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

// Object.keys():b遍历对象,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
var obj = {
    foo: 'bar',
    baz: 42
};
var result = Object.keys(obj)
console.log(result); // ["foo", "baz"]
// Object.values():b遍历对象,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
var obj = {
    foo: 'bar',
    baz: 42
};
var result = Object.values(obj)
console.log(result); // [ 'bar', 42 ]
//Object.entries():b遍历对象,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
var obj = {
    foo: 'bar',
    baz: 42
};
var result = Object.entries(obj)
console.log(result); // [ [ 'foo', 'bar' ], [ 'baz', 42 ] ]

ES2017 引入了跟Object.keys配套的Object.valuesObject.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]
}

Object.fromEntries()

Object.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。

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

该方法的主要目的,是将键值对的数据结构还原为对象,因此特别适合将 Map 结构转为对象。

// 例一
const entries = new Map([
  ['foo', 'bar'],
  ['baz', 42]
]);

Object.fromEntries(entries)
// { foo: "bar", baz: 42 }

// 例二
const map = new Map().set('foo', true).set('bar', false);
Object.fromEntries(map)
// { foo: true, bar: false }

 

posted @ 2021-07-26 16:41  半白半黑  阅读(156)  评论(0)    收藏  举报