【ES6】对象的新增方法

对象的新增方法

Object.assign()

Object.is()

Object.getOwnPropertyDescriptors()

Object.fromEntries()

遍历方法:

一、 Object.keys() 返回键名数组

二、 Object.values() 返回键值数组

三、 Object.entries() 返回键值对数组

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

一、 __proto__属性

二、 Object.setPrototypeOf()

三、 Object.getPrototypeOf()

Object.assign()

等同于对象扩展运算符(...),将源对象中的所有可枚举属性复制到目标对象中。只拷贝自身可枚举的属性。

属性名为 Symbol 值的属性,也会被 Object.assign() 拷贝。

只有一个参数,会直接返回该参数。如果参数不是对象,则会转成对象后再返回。

如果 undefined 和 null 作为首参数,会报错,因为无法将其转为对象。若不在首参数,则不报错。

如果源参数是字符串,会将字符串以数组形式拷贝到目标对象中。

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" }

只有字符串合入目标对象(以字符数组的形式),数值和布尔值都会被忽略。这是因为只有字符串的包装对象,会产生可枚举属性。

Object.assign() 可以用来处理数组,但是会把数组视为对象。

Object.assign([1, 2, 3], [4, 5]); // [4, 5, 3]

上面代码中,Object.assign() 把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性 4 覆盖了目标数组的 0 号属性 1 。

Object.assign() 只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。

Object.is()

它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。不同之处只有两个:

  1. +0 不等于-0

  2. NaN 等于自身

Object.getOwnPropertyDescriptors()

返回指定对象所有自身属性(非继承属性)的描述对象。

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.assign() 无法正确拷贝 get 属性和 set 属性的问题。Object.getOwnPropertyDescriptors() 方法配合 Object.defineProperties() 方法,就可以实现正确拷贝。

Object.getOwnPropertyDescriptors() 方法的另一个用处,是配合 Object.create() 方法,将对象属性克隆到一个新对象。这属于浅拷贝。

Object.getOwnPropertyDescriptors() 方法可以实现一个对象继承另一个对象。也可以用来实现 Mixin(混入)模式。

Object.fromEntries()

将一个键值对数组转为对象。是 Object.entries() 的逆操作。

可将 Map 结构转为对象。

const obj = Object.fromEntries([
  ["foo", "bar"],
  ["baz", 42],
]);

console.log(obj); // { foo: "bar", baz: 42 }

配合 URLSearchParams 对象,将查询字符串转为对象。

Object.fromEntries(new URLSearchParams("id=1001&opt=add")); // { id: "1001", opt: "add" }

遍历

Object.keys()

返回一个数组,由参数对象自身的可枚举属性的键名组成。

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

Object.keys(obj); // ["foo", "baz"]

Object.values()

返回一个数组,由参数对象自身的可枚举属性的键值组成。会过滤属性名为 Symbol 值的属性。

const obj = { 100: "a", 2: "b", 7: "c" };
Object.values(obj); // ["b", "c", "a"]

上面代码中,属性名为数值的属性,是按照数值大小,从小到大遍历的,因此返回的顺序是 b、c、a 。

如果参数是一个字符串,会返回各个字符组成的一个数组。

Object.values("Hi"); // ['H', 'i']

上面代码中,字符串会先转成类数组对象 { 0: 'H', 1: 'i' } 。

Object.values(42); // []
Object.values(true); // []

如果参数不是对象,会先将其转为对象。由于数值和布尔值的包装对象,都不会为实例添加非继承的属性,于是返回空数组。

Object.entries()

返回一个数组,由参数对象自身的可枚举属性的键值对(key-value)组成。

除了返回值不同,其他的行为与 Object.values() 基本一致。

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

const obj = { foo: "bar", baz: 42 };
const map = new Map(Object.entries(obj));
map; // Map { foo: "bar", baz: 42 }

操作原型对象

__proto__属性

(前后各两个下划线)

用来读取或设置当前对象的原型对象。

从语义和兼容性角度来说,最好使用 Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。

Object.setPrototypeOf()

设置一个对象的原型对象,返回参数对象本身。是 ES6 正式推荐的设置原型对象的方法。

两个参数:

  • object 第一个参数。当前对象。如果不是对象,会自动转为对象。如果是 undefied 或者 null , 则会报错。

  • prototype 第二个参数。原型对象。

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()

读取一个对象的原型对象。

一个参数:

  • obj 当前对象。
posted @ 2021-11-03 17:04  等等啦  阅读(260)  评论(0)    收藏  举报