跳到主要内容

对象字面量扩展语法ES6

1. 简写属性

如果使用基本的对象字面量语法,需要把每个标识符都重复两次。

ES5旧的语法
let x = 1,
y = 2
let o = {
x: x,
y: y,
}

在 ES6 及之后,可以删掉其中的分号和一份标识符,得到非常简洁的代码。

ES6简写语法
let x = 1,
y = 2
let o = { x, y }
console.log(o.x + o.y) // =>3

2. 计算的属性名

计算的属性名,就是属性名是动态的

es5写法
const PROPERTY_NAME = 'p1'
function computePropertyName() {
return 'p' + 2
}
let o = {}
o[PROPERTY_NAME] = 1
o[computePropertyName()] = 2
console.log(o) // => {p1: 1, p2: 2}

ES6 称为计算属性的特性可以更简单地创建类似对象。

ES6语法:可以让你直接把前面代码中的方括号放在对象字面量中
const PROPERTY_NAME = 'p1'
function computePropertyName() {
return 'p' + 2
}
let p = {
[PROPERTY_NAME]: 1,
[computePropertyName()]: 2,
}
console.log(p.p1 + p.p2) // => 3

3. 符号作为属性名

计算属性语法也让另一个非常重要的对象字面量特性成为可能。

  • 在 ES6 及之后,属性名可以是字符串或符号。
  • 如果把符号赋值给一个变量或常量,那么可以使用计算属性语法将该符号作为属性名;
const extension = Symbol('my extension symbol')
let o = {
[extension]: {},
}
o[extension].x = 0 //这个属性不会与o对其他属性冲突

Symbol()符号

  1. Symbol()符号除了用作属性名之外,不能用它们做任何事情。
  2. 每个符号都跟其他的符号不同,这就意味着符号非常适合用于创建唯一属性名。
  3. Symbol()符号返回的值不等于任何其他符号或其他值。可以传一个字符串给 Symbol()符号,但也只是作为辅助调式使用。
  4. 使用两个通用参数的 Symbol()符号,返回的值也是不一样的。
  5. 使用符号不是为了安全,而是为了 JavaScript 对象定义安全的扩展机制。
  6. 可以使用 Object.getOwnPropertySymbols()找到使用的符号属性,然后修改或删除。

4. 扩展操作符 ...

  • 它是仅在对象字面量中有效的一种特殊语法。
  • 扩展操作符只扩展对象的自有属性,不扩展任何继承属性。
  • 如果用多了可能出现性能瓶颈,所以建议少用。特别是在循环和递归函数中。
  • 如果对象有 n 个属性,把这个属性扩展到另外一个对象可能是一种 O(n)操作。
let position = { x: 0, y: 0 }
let dimensions = { width: 100, height: 75 }
let rect = { ...position, ...dimensions }
console.log(rect.x + rect.y + rect.width + rect.height) // =>175

5. 简写方法

在把函数定义为对象属性时,我们称该函数为方法。

ES6以前写法
let square = {
area: function () {
return this.side * this.side
},
side: 10,
}
square.area()
现在ES6简写方法
let square = {
area() {
return this.side * this.side
},
side: 10,
}
square.area()
  • 简写语法让人一看便知 area()是方法,而不是像 side 一样看起来像数据属性。
  • 使用这个简写语法,属性名可以是对象字面量允许的任何形式。可以是字符串,字符串字面量和计算的属性名、符号属性名。
const METHOD_NAME = 'm'
const symbol = Symbol()
let weirdMethods = {
'method With Spaces'(x) {
return x + 1
},
[METHOD_NAME](x) {
return x + 2
},
[symbol](x) {
return x + 3
},
}
console.log(weirdMethods['method With Spaces'](1))
console.log(weirdMethods[METHOD_NAME](1))
console.log(weirdMethods[symbol](1))

为了让对象可迭代,以便在 for/of 循环中使用,必须以符号名 Symbol.iterator 为它定义一个方法。

6. 属性的获取方法和设置方法

  • 到目前为止,讨论的对象属性都是数据属性。数据属性:即有一个名字和一个普通的值。
  • 对象除了数据属性,JavaScript 还可以定义访问器属性(accessor property)

定义访问器属性(accessor property)

  • 这种属性不是一个值
  • 而是一个或两个访问器方法:
  • 一个获取方法(getter)
  • 一个设置方法(setter)
  • 如果一个属性既有获取方法也有设置方法,则该属性是一个可读写属性。
  • 如果只有一个获取方法,那它就是只读属性。
  • 如果只有一个设置方法,那它就是只写属性,读取这种属性始终返回 undefined
let o={
// 一个普通的数据属性
dataProp:value,

// 通过一对函数定义的一个访问器属性
get accessorProp(){return this.dataProp;}
set accessorProp(value){this.dataProp = value;}
}

访问器属性是通过一个或者两个方法来定义的。方法名就是属性名。

const serialnum = {
_n: 0,
get next() {
return this._n++
},
set next(n) {
if (n > this._n) this._n = n
else throw new Error('值不能重复')
},
}

serialnum.next = 100
console.log(serialnum.next) // =>100
console.log(serialnum.next) // =>101
console.log(serialnum.next) // =>102

通过 访问器属性 获得随机数

这个对象的访问器属性返回随机数值
// 这个对象的访问器属性返回随机数值
const random = {
get octer() {
return Math.floor(Math.random() * 256)
},
get uint16() {
return Math.floor(Math.random() * 256)
},
get int16() {
return Math.floor(Math.random() * 256)
},
}
console.log(random.octer)
console.log(random.uint16)
console.log(random.int16)