ES6 day2

对象扩展

ES6 一共有 5 种方法可以遍历对象的属性。

(1)for...in

for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

(2)Object.keys(obj)

Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

(5)Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。


super 关键字

super指向当前对象的原型对象

const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};

Object.setPrototypeOf(obj, proto);
obj.find() // "hello"

Object.is()

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

Object.is('foo', 'foo')
// true
Object.is({}, {})
// false

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

Object.assign()

Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

const target = { a: 1 };

const source1 = { b: 2 };
const source2 = { c: 3 };

Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。

如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

如果该参数不是对象,则会先转成对象,然后返回。

typeof Object.assign(2) // "object"


上面代码中,v1v2v3分别是字符串、布尔值和数值,结果只有字符串合入目标对象(以字符数组的形式),数值和布尔值都会被忽略。这是因为只有字符串的包装对象,会产生可枚举属性。

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

注意点

  • 浅拷贝

    源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

    const obj1 = {a: {b: 1}};
    const obj2 = Object.assign({}, obj1);
    
    obj1.a.b = 2;
    obj2.a.b // 2
    

  • 同名属性的替换

    一旦遇到同名属性,Object.assign()的处理方法是替换,而不是添加。

    const target = { a: { b: 'c', d: 'e' } }
    const source = { a: { b: 'hello' } }
    Object.assign(target, source)
    // { a: { b: 'hello' } }
    

  • 数组的处理

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

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

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


  • 取值函数的处理

    复制函数的返回值

    const source = {
      get foo() { return 1 }
    };
    const target = {};
    
    Object.assign(target, source)
    // { foo: 1 }
    

常用点

  • 为对象添加属性

    class Point {  constructor(x, y) {    Object.assign(this, {x, y});  }}
    

  • 为对象添加方法

    Object.assign(SomeClass.prototype, {  someMethod(arg1, arg2) {    ···  },  anotherMethod() {    ···  }});// 等同于下面的写法SomeClass.prototype.someMethod = function (arg1, arg2) {  ···};SomeClass.prototype.anotherMethod = function () {  ···};
    

  • 克隆对象

    采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。

    当克隆对象只有一级时候可以看做深拷贝

    function clone(origin) {  return Object.assign({}, origin);}
    

  • 合并多个对象

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

  • 为属性指定默认值

    const DEFAULTS = {  logLevel: 0,  outputFormat: 'html'};function processContent(options) {  options = Object.assign({}, DEFAULTS, options);  console.log(options);  // ...}
    

    Object.assign()方法将DEFAULTSoptions合并成一个新对象,如果两者有同名属性,则options的属性值会覆盖DEFAULTS的属性值。


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

__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()

__proto__属性,用来读取或设置当前对象的原型对象

// es5 的写法const obj = {  method: function() { ... }};obj.__proto__ = someOtherObj;// es6 的写法var obj = Object.create(someOtherObj);obj.method = function() { ... };

Object.setPrototypeOf()

用来设置一个对象的原型对象

let proto = {};let obj = { x: 10 };Object.setPrototypeOf(obj, proto);proto.y = 20;proto.z = 40;obj.x // 10obj.y // 20obj.z // 40

Object.getPrototypeOf()

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

function Rectangle() {  // ...}const rec = new Rectangle();Object.getPrototypeOf(rec) === Rectangle.prototype// trueObject.setPrototypeOf(rec, Object.prototype);Object.getPrototypeOf(rec) === Rectangle.prototype// false

Object.keys(),Object.values(),Object.entries()

Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

var obj = { foo: 'bar', baz: 42 };Object.keys(obj)// ["foo", "baz"]

Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。

const obj = { foo: 'bar', baz: 42 };Object.values(obj)// ["bar", 42]

Object.entries()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

const obj = { foo: 'bar', baz: 42 };Object.entries(obj)// [ ["foo", "bar"], ["baz", 42] ]