ES6学习笔记13:对象新增的方法

对象新增的方法

Object.is()

在ES5中比较两个值是否相等,可以使用相等运算符(==)和严格相等运算符(===

  • 相等运算符会自动转换数据类型(缺点)
  • 严格相等运算符NaN不等于自身,+0等于-0。(缺点)

方法Object.is用来比较两个值是否严格相等,和严格相等运算符的行为一致,但是

  1. +0不等于-0
  2. NaN等于自身

Object.assign()

方法Object.assign()用于对象合并,将源对象的所有可枚举的属性复制到目标对象,Object.assign()方法的第一个参数是目标对象,剩下的参数都是源对象。

  • 如果目标对象与源对象存在同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性
  • undefinednull不能作为第一个参数,否则会报错
  • undefinednull可以作为第二个或之后参数,由于无法转换,所以会直接跳过。
  • 其他类型的值不在第一个参数,也不会报错。除了字符串会以数组的形式拷贝到目标对象,其他的不会产生效果
  • Object.assign()只拷贝对象自身属性,不拷贝继承属性,也不拷贝枚举属性
  • Object.assign()是浅拷贝
  • 同名属性替换
  • 会将数组作为对象处理
  • 当复制的是一个取值函数,那么会先求值再复制
应用
  1. 为对象添加属性
class Point {
  constructor(x ,y ){
    Object.assign(this, {x,y});
  }
}
  1. 为对象添加方法
Object.assign(someClass.prototype, {
  someMethod(arg1,arg2){
    ....
  }
});
//  等同于
someClass.prototype.someMethod = function (arg1,arg2){
  ...
}
  1. 克隆对象
function clone(origin){
  return Object.assign({},origin);
}

上面只是克隆原对象自身。

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

上面的代码会保持继承链

  1. 合并多个对象

将多个对象合并到某一个对象

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

如果合并后返回一个新对象,需要稍作修改

const merge = (...source) => Object.assign({}, ...source);
  1. 为属性指定默认值
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()用于读取一个对象的原型对象

  • 如果参数不是对象,会自动转换为对象
  • 如果参数是undefinednull,由于无法转换成对象,所以会报错

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 入门》所做的笔记,大部分例子来源于此书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值