ES6对象新增的扩展

184 阅读5分钟

image.png

一、属性的简写

  • ES6中,当对象键名与对应值名相等的时候,可以进行简写
  • 方法也能进行简写
  • 注意:简写的对象方法不能用作构造函数,否则会报错
// 属性名简写
const baz = {foo:foo}
// 等同于
const baz = {foo}

// 方法简写
const o = {
    method() {
        return "Hello!";
    }
};
// 等同于
const o = {
    method: function() {
        return "Hello!";
    }
}

// 简写的对象方法不能用作构造函数,否则会报错
const obj = {
  f() {
    this.foo = 'bar';
  }
};
new obj.f() // 报错

二、属性名表达式

  • ES6允许使用表达式作为对象的属性名,这使得动态属性名成为可能
  • 方法名也可用表达式定义
  • 注意,属性名表达式与简洁表示法,不能同时使用,会报错
  • 注意,属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]
// 变量作为对象的属性名
const propName = "age";
const person = {
    [propName]: 25
};
console.log(person.age, person[propName]); // 输出: 25 25

// 方法名也可用表达式定义
let obj = {
    ['h' + 'ello']() {
        return 'hi';
    }
};
obj.hello() // hi

// 属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串`[object Object]`
const keyA = { a: 1 };
const keyB = { b: 2 };
const myObject = {
    [keyA]: "valueA",
    [keyB]: "valueB",
};
console.log(myObject); // 输出: Object {[object Object]: "valueB"}

三、super关键字

this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象

四、 扩展运算符

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x   // 1
y   // 2
z   // { a: 3, b: 4 }

const person = { name: 'John', age: 30 };
const clone = { ...person }; // 克隆对象
const merged = { ...person, job: 'Developer' }; // 合并对象并添加新属性

注:解构赋值是浅拷贝

对象的扩展运算符等同于使用Object.assign()方法

五、属性的遍历

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

  • for...in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
  • Object.keys(obj)返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名
  • Object.getOwnPropertyNames(obj)返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名
  • Object.getOwnPropertySymbols(obj)返回一个数组,包含对象自身的所有 Symbol 属性的键名
  • Reflect.ownKeys(obj)返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举

上述遍历,都遵守同样的属性遍历的次序规则:

  • 首先遍历所有数值键,按照数值升序排列
  • 其次遍历所有字符串键,按照加入时间升序排列
  • 最后遍历所有 Symbol 键,按照加入时间升序排
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]

六、对象新增的方法

关于对象新增的方法,分别有以下:

  1. Object.is(value1, value2)
  2. Object.assign(target, sources)
  3. Object.getOwnPropertyDescriptors()
  4. Object.setPrototypeOf(),Object.getPrototypeOf()
  5. Object.keys(obj),Object.values(obj),Object.entries(obj)(ES8)
  6. Object.fromEntries()
  7. Object.freeze(obj), Object.seal() , Object.preventExtensions()禁止对象扩展

1、Object.is(value1, value2)

严格判断两个值是否相等,与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。(Object.is() 在比较两个非原始值(如NaN和-0)时更为严格。)

console.log(Object.is('foo', 'foo')); // true
console.log(Object.is({}, {})); // false,因为它们是两个不同的对象

2、Object.assign(target, sources)

浅拷贝

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

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

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target, returnedTarget); // 输出: { a: 1, b: 4, c: 5 } { a: 1, b: 4, c: 5 }

3、Object.getOwnPropertyDescriptors()

返回指定对象所有自身属性(非继承属性)的描述对象

const obj = {
    foo: 123,
    get bar() {
      return "abc";
    },
};
console.log(Object.getOwnPropertyDescriptors(obj));
// 输出:
// { foo:
//    { value: 123,
//      writable: true,
//      enumerable: true,
//      configurable: true },
//   bar:
//    { get: [Function: get bar],
//      set: undefined,
//      enumerable: true,
//      configurable: true }
//}

4、Object.setPrototypeOf()、Object.getPrototypeOf()

Object.setPrototypeOf方法用来设置一个对象的原型对象

Object.getPrototypeOf()方法用于读取一个对象的原型对象

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

Object.keys()

返回自身的(不含继承的)所有可遍历(enumerable)属性的键名的数组

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

Object.values()

返回自身的(不含继承的)所有可遍历(enumerable)属性的键对应的数组

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

Object.entries()

返回一个对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对的数组

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

6、 Object.fromEntries()

用于将一个键值对数组转为对象

	Object.fromEntries([	  ['foo''bar'],
	  ['baz', 42]
	])
	// { foo: "bar", baz: 42 }

七、解构赋值

解构赋值允许你从数组对象中提取数据到一个变量中,非常适合处理函数返回的多个值。

const person = { name: 'John', age: 30 }
const { name, age } = person
console.log(name); // 输出: John
console.log(age); // 输出: 30

八、Proxy对象

Proxy 是 ES6 为了操作对象引入的 API 。
Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。

   let star = {
   name: '我是A',
   age: 18
   }
   let proxy = new Proxy(star,{
       get(targetObj, propoty, receiver) {
           console.log(`我是被代理的对象${targetObj}`)  // 我是被代理的对象[object Object]
           console.log(`我是你访问的被代理的属性${propoty}`) // 我是你访问的被代理的属性name
           //receiver是代理对象proxy
           return targetObj[propoty]
       }
   })
   console.log(proxy.name); // 我是A

九、ES5之前的常用的对象方法

1、Object.creat(obj)

2、Object.prototype.hasOwnProperty()

方法返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性。

如果指定的属性是对象的直接属性,则该方法返回 true — 即使值为 null 或未定义。

如果该属性是继承的或根本没有声明,则返回 false。

语法:obj.hasOwnProperty(prop)

参数:prop:要测试的属性的字符串名称或符号。

返回值:如果对象将指定的属性作为自己的属性,则返回true;否则为false。

3、Object.prototype.toString()

toString() 方法返回一个表示对象的字符串。

当对象将被表示为文本值或以期望字符串的方式引用对象时。

语法:obj.toString()

返回值:表示对象的字符串。