ES6 系列十一:对象的拓展

"Code tailor",为前端开发者提供技术相关资讯以及系列基础文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。

前言

在开始学习以前,咱们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 "对象的扩展" 章节的总结,若是您已掌握下面知识事项,则可跳过此环节直接进入题目练习javascript

  • 对象如何简洁表达 ?
  • 属性遍历的方法有哪些 ?
  • 什么是 super 运算符 ?
  • 对象扩展运算符有哪些做用 ?

若是您对某些部分有些遗忘,👇🏻 已经为您准备好了!前端

学习连接

对象的扩展学习java

汇总总结

对象的简洁表达

ES6 容许在大括号里面,直接写入变量和函数,做为对象的属性和方法
let birth = '1999/01/01'

const Person = {
  name: '李四',

  //等同于birth: birth
  birth,

  // 等同于hello: function ()...
  hello() {
    console.log('个人名字是', this.name)
  },
}

属性遍历

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

以上的 5 种方法遍历对象的键名,都遵照一样的属性遍历的次序规则。es6

  • 首先遍历全部数值键,按照数值升序排列。
  • 其次遍历全部字符串键,按照加入时间升序排列。
  • 最后遍历全部 Symbol 键,按照加入时间升序排列。

super 运算符

指向当前对象的原型对象
const proto = {
  foo: 'hello',
}

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

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

//上面代码中,对象obj.find()方法之中,经过super.foo引用了原型对象proto的foo属性。

注意,super 关键字表示原型对象时,只能用在对象的方法之中,用在其余地方都会报错。数组

对象扩展运算符

1. 解构赋值微信

对象的解构赋值用于从一个对象取值,至关于将目标对象自身的全部可遍历的( enumerable )、但还没有被读取的属性,分配到指定的对象上面。全部的键和它们的值,都会拷贝到新对象上面。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }
x // 1
y // 2
z // { a: 3, b: 4 }

//变量z是解构赋值所在的对象。它获取等号右边的全部还没有读取的键(a和b)
//将它们连同值一块儿拷贝过来。

注意: 函数

  • 解构赋值要求等号右边是一个对象,因此若是等号右边是 undefinednull ,就会报错,由于它们没法转为对象。
  • 解构赋值必须是最后一个参数,不然会报错。
  • 解构赋值的拷贝是浅拷贝,即若是一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。
let obj = { a: { b: 1 } }
let { ...x } = obj
obj.a.b = 2
x.a.b // 2
  • 扩展运算符的解构赋值,不能复制继承自原型对象的属性

1. 扩展运算符学习

取出参数对象的全部可遍历属性,拷贝到当前对象之中。
let z = { a: 3, b: 4 }
let n = { ...z }
n // { a: 3, b: 4 }

注意: this

  • 对象的扩展运算符也能够用于数组。
let foo = { ...['a', 'b', 'c'] }
foo
// {0: "a", 1: "b", 2: "c"}
  • 若是扩展运算符后面是一个空对象,则没有任何效果。
{...{}, a: 1}
// { a: 1 }
  • 若是扩展运算符后面不是对象,则会自动将其转为对象。
// 等同于 {...Object(1)}
{...1} // {}
  • 对象的扩展运算符等同于使用 Object.assign() 方法。
let aClone = { ...a }
// 等同于
let aClone = Object.assign({}, a)

题目自测

一: 使用扩展运算符,进行深拷贝,将 obj1 的内容拷贝到 obj2 中(不考虑对象嵌套的问题).code


二: 如下哪一种方式为不正确的定义字面量对象的方法?

A.

var obj = {
  foo: true,
  abc: 123,
}

B.

let propKey = 'foo'

let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123,
}

C.

const foo = 'bar'
const baz = { [foo]: 'abc' }

D.

const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };

三: 如下三个对象使用扩展运算符进行拼接,输出结果是什么?

let obj1 = { name: 'hzq', age: 18 }
let obj2 = { name: 'yry', age: 19 }
let obj3 = { name: 'ljj', age: 20, role: 'boss' }
let obj4 = { ...obj1, ...obj2, ...obj3 }
console.log(obj4) // {name: 'ljj', age: 20, role: 'boss'}

题目解析

1、

Answer:

let obj1 = { name: 'hzq', age: 18 }
let obj2 = { ...obj1 }

对象中的扩展运算符(...)用于取出参数对象中的全部可遍历属性,拷贝到当前对象之中

2、

Answer:D

A 选项为标准的 ES5 定义字面量对象的方法。B 选项为 ES6 中,在大括号中,容许使用表达式做为对象属性名。C 选项如同 B 选项。D 选项的错误在于,属性名表达式与简洁表示法没法同时使用。

3、

Answer:

扩展运算符的使用将obj1,obj2,obj3三个变成{name: 'hzq', age: 18, name: 'yry', age:19, name: 'ljj', age:20, role:'boss'}

这里有一个注意点就是:若是是对象的拼接,对于同一个 key 的键值对,后面的会覆盖前面的

因此最终结果变就是{name: 'ljj', age:20, role:'boss'}

相关文章
相关标签/搜索