文章目录
对象新增的方法
Object.is()
在ES5中比较两个值是否相等,可以使用相等运算符(==
)和严格相等运算符(===
)
- 相等运算符会自动转换数据类型(缺点)
- 严格相等运算符
NaN
不等于自身,+0
等于-0
。(缺点)
方法Object.is
用来比较两个值是否严格相等,和严格相等运算符的行为一致,但是
+0
不等于-0
NaN
等于自身
Object.assign()
方法Object.assign()
用于对象合并,将源对象的所有可枚举的属性复制到目标对象,Object.assign()
方法的第一个参数是目标对象,剩下的参数都是源对象。
- 如果目标对象与源对象存在同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性
undefined
和null
不能作为第一个参数,否则会报错undefined
和null
可以作为第二个或之后参数,由于无法转换,所以会直接跳过。- 其他类型的值不在第一个参数,也不会报错。除了字符串会以数组的形式拷贝到目标对象,其他的不会产生效果
Object.assign()
只拷贝对象自身属性,不拷贝继承属性,也不拷贝枚举属性
Object.assign()
是浅拷贝- 同名属性替换
- 会将数组作为对象处理
- 当复制的是一个取值函数,那么会先求值再复制
应用
- 为对象添加属性
class Point {
constructor(x ,y ){
Object.assign(this, {x,y});
}
}
- 为对象添加方法
Object.assign(someClass.prototype, {
someMethod(arg1,arg2){
....
}
});
// 等同于
someClass.prototype.someMethod = function (arg1,arg2){
...
}
- 克隆对象
function clone(origin){
return Object.assign({},origin);
}
上面只是克隆原对象自身。
function clone(origin){
const originProto = Object.getPrototypeof(origin);
return Object.assign(Object.create(originProto),origin);
}
上面的代码会保持继承链
- 合并多个对象
将多个对象合并到某一个对象
const merge = (target, ...source) => Object.assign(target,...source);
如果合并后返回一个新对象,需要稍作修改
const merge = (...source) => Object.assign({}, ...source);
- 为属性指定默认值
const Defaults = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options){
options = Object.assign({},Defaults,options);
// ...
}
由于存在浅拷贝的问题,Defaults
对象和options
对象的所有属性的值,最好都是简单类型,不要指向另一个对象,否则,Defaults
对象的该属性很可能不起作用。
Object.getOwnPropertyDescriptors()
ES5的Object.getOwnPropertyDescriptor()
方法会返回某个对象属性的描述对象
ES2017引入了Object.getOwnPropertyDescriptors()
返回指定对象所有自身属性(非继承属性)的描述对象。
引入的目的
-
解决方法
Object.assign()
无法正确拷贝get
属性和set
属性的问题 -
配合
Object.create()
方法将对象属性克隆到一个新对象(浅拷贝) -
实现一个对象继承另一个对象
之前继承对象
const obj = {
_proto_: prot,
foo:123,
};
ES6规定的_proto_
需要看浏览器的支持性,如果不用_proto_
就需要做如下修改:
const obj = Object.create(prot);
obj.foo = 123;
// 或者
const obj = Object.assign(Object.create(prot),{foo:132,});
使用Object.getPropertyDescriptors()
const obj = Object.create(
prot,
Object.getOwnPropertyDescriptors({
foo:123,
})
)
_proto_属性,Object.setPrototypeOf(),Object.getPrototypeOf()
_proto_属性
属性_proto_
用来读取或者设置当前对象的prototype
对象。目前所有浏览器(包括IE11)都有这个属性。
无论从语义、兼容性的角度来看,都不要使用这个属性
使用Object.setPrototypeOf()
(写)、Object.getPrototypeOf()
(读)、Object.create()
(生成)代替
Object.setPrototypeOf()
方法Object.setPrototypeOf()
与_proto_
相同,用来设置一个对象的prototype
对象,返回参数对象本身。
Object.getPrototypeOf()
方法Object.getPrototypeOf()
用于读取一个对象的原型对象
- 如果参数不是对象,会自动转换为对象
- 如果参数是
undefined
或null
,由于无法转换成对象,所以会报错
Object.keys(),Object.values(),Object.entries()
- 方法
Object.keys()
返回一个数组,数组元素是参数对象自身(不含继承)的所有可遍历属性的键名。
const obj = {foo: 'bar', baz: 42};
Object.keys(obj); // ['foo','baz']
- 方法
Object.values()
返回一个数组,数组元素是参数对象自身的(不含继承的)所有可遍历属性的键值
const obj = {foo: 'bar', baz: 42};
Object.values(obj); // ['bar',42]
注意:
Object.values
会过滤属性名为Symbol值的属性- 当参数是一个字符串,会返回各个字符串组成的一个数组
- 当参数不是对象,
Object.values
会将它转为对象,由于数值和布尔值的包装对象都不会为实例添加非继承的属性,所以Object.values
返回一个空数组
Object.values(42); // []
Object.values('QQ'); // ['Q','Q']
Object.values(true); // []
- 方法
Object.entries()
返回一个数组,数组元素是参数对象自身的(不含继承的)所有可遍历属性的键值对数组
const obj = {foo: 'bar', baz: 1234};
Object.entries(obj); // [ [ 'foo' , 'bar' ] , [ 'baz', 1234 ] ]
注意:
- 如果原对象的属性名是一个Symbol值,这个属性会被忽略
用途:
- 遍历对象的属
- 将对象转为
Map
解构
实现Object.entries()
Generator函数版本
function* entries(obj){
for (let key of Object.keys(obj)){
yield [key, obj[key]];
}
}
非Generator函数版本
function entries(obj){
let arr =[];
for (let key of Object.keys(obj)){
arr.push([key, obj[key]]);
}
return arr;
}
Object.fromEntries()
方法Object.fromEntries()
是Object.entries()
的逆操作。,用于将一个键值对数组转为对象
- 特别适合Map解构转为对象
- 配合
URLSearchParams
对象,将查询字符串转为对象
Object.fromEntries(new URLSearchParams('foo=bar&baz=ss')); // {foo: 'bar', baz: 'ss'}
备注:本文是自己学习阮一峰老师的《ECMAScript 6 入门》所做的笔记,大部分例子来源于此书。