乐趣区

关于javascript:ES6-系列十一对象的拓展

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

前言

在开始学习之前,咱们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 “ 对象的扩大 ” 章节的总结,如果您已把握上面常识事项,则可跳过此环节间接进入题目练习

  • 对象如何简洁表白?
  • 属性遍历的办法有哪些?
  • 什么是 super 运算符?
  • 对象扩大运算符有哪些作用?

如果您对某些局部有些忘记,👇🏻 曾经为您筹备好了!

学习链接

对象的扩大学习

汇总总结

对象的简洁表白

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 种办法遍历对象的键名,都恪守同样的属性遍历的秩序规定。

  • 首先遍历所有数值键,依照数值升序排列。
  • 其次遍历所有字符串键,依照退出工夫升序排列。
  • 最初遍历所有 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}

留神:

  • 对象的扩大运算符也能够用于数组。
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 中(不思考对象嵌套的问题).


二: 以下哪种形式为不正确的定义字面量对象的办法?

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

题目解析

一、

Answer:

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

对象中的扩大运算符 (...) 用于取出参数对象中的所有可遍历属性,拷贝到以后对象之中

二、

Answer:D

A 选项为规范的 ES5 定义字面量对象的办法。B 选项为 ES6 中,在大括号中,容许应用表达式作为对象属性名。C 选项如同 B 选项。D 选项的谬误在于,属性名表达式与简洁表示法无奈同时应用。

三、

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

退出移动版