【ES6】对象的新增方法
对象的新增方法
Object.getOwnPropertyDescriptors()
遍历方法:
一、 Object.keys() 返回键名数组
二、 Object.values() 返回键值数组
三、 Object.entries() 返回键值对数组
JavaScript 语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法:
一、 __proto__属性
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()
它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。不同之处只有两个:
-
+0 不等于-0
-
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 当前对象。

浙公网安备 33010602011771号