# ES6之对象的新增方法
# 一. Object.is()
Object.is()
用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
Object.is('a', 'a')
// true
Object.is({}, {})
// false
2
3
4
不同点 ==
会进行类型转换,===
的NaN不等于自身,且两者+0
等于-0
// ES5
+0 == -0 //true
NaN === NaN // false
// ES6
Object.is(5, '5') // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
2
3
4
5
6
7
8
# 二. Object.assign()
Object.assign()
方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 };
const src1= { b: 2 };
const src2= { c: 3 };
Object.assign(target, src1, src2);
target // {a:1, b:2, c:3}
// 如果目标对象与源对象出现同名属性,则后面的属性会覆盖前面的属性
const target = { a: 1, b: 1 };
const src1= { b: 2, c: 2 };
const src2= { c: 3 };
Object.assign(target, src1, src2);
target // {a:1, b:2, c:3}
// 只有一个参数,会直接返回该参数
const obj = {a: 1};
Object.assign(obj) === obj // true
// 如果该参数不是对象,则会先转成对象,然后返回
typeof Object.assign(2) // "object"
// undefined,null无法转成对象,会报错
Object.assign(undefined) // 报错
Object.assign(null) // 报错
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
注意: Object.assign()方法实行的是浅拷贝,而不是深拷贝
# 常见用途
- 为对象添加属性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
2
3
4
5
- 为对象添加方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 克隆对象
let newObj = Object.assign({}, origin)
- 合并多个对象
// 将多个对象合并到某个对象
const merge = (target, ...sources) => Object.assign(target, ...sources);
// 合并后返回一个新对象
const merge = (...sources) => Object.assign({}, ...sources);
2
3
4
5
- 指定默认值
const DEFAULTS = {
age: 18,
sex: '男'
};
function handle(options) {
options = Object.assign({}, DEFAULTS, options);
console.log(options);
// ...
}
2
3
4
5
6
7
8
9
10
# 三. Object.getOwnPropertyDescriptors()
ES5 的Object.getOwnPropertyDescriptor()
方法会返回某个对象属性的描述对象;
ES6 的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 } }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 四. Object.setPrototypeOf(),Object.getPrototypeOf()
Object.setPrototypeOf()
用来设置一个对象的原型对象(prototype),返回参数对象本身
// 格式
Object.setPrototypeOf(object, 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
//如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。
Object.setPrototypeOf(1, {}) === 1 // true
Object.setPrototypeOf('foo', {}) === 'foo' // true
Object.setPrototypeOf(true, {}) === true // true
//如果第一个参数是undefined或null,会报错。
Object.setPrototypeOf(undefined, {})
// TypeError: Object.setPrototypeOf called on null or undefined
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Object.setPrototypeOf
方法,用于读取一个对象的原型对象
// 格式
Object.getPrototypeOf(obj);
// 示例
function Rectangle() {
// ...
}
const rec = new Rectangle();
Object.getPrototypeOf(rec) === Rectangle.prototype // true
Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype // false
// 如果参数不是对象,会被自动转为对象
// 等同于 Object.getPrototypeOf(Number(1))
Object.getPrototypeOf(1)
// Number {[[PrimitiveValue]]: 0}
Object.getPrototypeOf(1) === Number.prototype // true
//如果第一个参数是undefined或null,会报错。
Object.getPrototypeOf(null)
// TypeError: Cannot convert undefined or null to object
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 五. Object.keys(),Object.values(),Object.entries(),Object.fromEntries()
ES5 引入了Object.keys
方法,返回一个给定对象的自身可枚举属性组成的数组
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]
2
3
ES2017 引入了跟Object.keys
配套的Object.values
和bject.entries
,作为遍历一个对象的补充手段,供for...of循环使用。
Object.values()
方法返回一个给定对象自身的所有可枚举属性值的数组
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["bar", "42"]
2
3
Object.entries()
方法返回一个给定对象自身可枚举属性的键值对数组
const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]
// 实例
2
3
4
5
Object.entries()
用途
// 用途1:遍历对象的属性
let obj = { one: 1, two: 2 };
for (let [k, v] of Object.entries(obj)) {
console.log(
`${JSON.stringify(k)}: ${JSON.stringify(v)}`
);
}
// "one": 1
// "two": 2
// 用途2:将对象转为真正的Map结构
const obj = { foo: 'bar', baz: 42 };
const map = new Map(Object.entries(obj));
map // Map { foo: "bar", baz: 42 }
2
3
4
5
6
7
8
9
10
11
12
13
14
Object.fromEntries()
方法是Object.entries()
的逆操作,用于将一个键值对数组转为对象。
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }
2
3
4
5
###六. Object.hasOwn()
JavaScript 对象的属性分成两种:自身的属性和继承的属性。
ES5使用对象实例的hasOwnProperty()
方法,可以判断某个属性是否为原生属性。
ES2022 在Object对象上面新增了一个静态方法Object.hasOwn(),也可以判断是否为自身的属性。
const foo = Object.create({ a: 123 });
foo.b = 456;
Object.hasOwn(foo, 'a') // false
Object.hasOwn(foo, 'b') // true
2
3
4
5
区别 Object.hasOwn()对于不继承Object.prototype的对象不会报错,而hasOwnProperty()会报错。
const obj = Object.create(null);
obj.hasOwnProperty('foo') // 报错
Object.hasOwn(obj, 'foo') // false
2
3
4
注:本文只记录了日常开发中常用的更新