Skip to content
On this page

基本数据处理 · 对象字面量


第 3 节 基本数据处理 · 对象字面量

“都这么大了,还找不到对象吗?”
“不用找,我可以 new 一个。”

对象是 JavaScript 中的基础,它可以用于表达具象的事物,可以表达抽象的事物,也可以将具象事物抽象表达,反之亦然。

3.1 描述万物的对象

我是小问,多领域开发者,主要为 Web 开发与大数据、机器学习领域。

若要根据这段个人介绍,将笔者使用 JavaScript 进行抽象化表达,便可以使用对象字面量来实现。

const author = {
  name: '小问',
  title: '多领域开发者',
  domains: [ 'Web 开发', '大数据', '机器学习' ]
}

const someone = {
  name: 'Ben',
  age: 25,
  title: 'Web Developer',
  skills: [ 'JavaScript', 'TypeScript', 'HTML', 'CSS', 'React', 'MobX' ]
}

对象字面量可以将一个具象的事物在计算机程序中抽象化表达,但同时也可以将一个抽象的事物变得更为具象,就好比这一篇文章原本是一个抽象的事物,而在程序中却可以将其具象化表达。

const post = {
  title: '基本数据处理 · 对象字面量',
  serialNo: 2,
  parentBook: {
    title: '基于 JavaScript 开发灵活的数据应用',
    author: {
      name: '小问',
      title: '多领域开发者',
      domains: [ 'Web 开发', '大数据', '机器学习' ]
    }
  },
  
  content: '......'
}

当然对象的属性键(Key)也并非只能用这样的方式定义,如果说需要为一个数值定义一些数学特征值,包括底数为 2 的对数、底数为自然对数 e 的对数以及底数为 10 的对数。

const x = 1024

function getBaseLog(base, x) {
  return Math.log(x) / Math.log(base)
}

const baseLog = {
  2: getBaseLog(2, x),
  e: getBaseLog(Math.E, x),
  10: getBaseLog(10, x)
}

console.log(baseLog) //=> {2: 10, 10: 3.0102999566398116, e: 6.931471805599453}

当需要描述的事物更加抽象时,可能连属性键都会是动态生成的,那么这时候就需要更高级的语法来实现这样的需求了。

const prefix = 'MK'
const sourceVersion = 1
const latestVersion = 47

const ironMan = {
  [prefix + sourceVersion]: '2008',
  [prefix + latestVersion]: '2017'
}

console.log(ironMan.MK47) //=> 2017

{ [<expression>]: value } 中的 expression 为一个表达式,即可以计算出结果的代码,如上面一段代码的 prefix + sourceVersion

3.2 对象内容操作

对象被定义以后,自然就是对其的使用,而最直接的便是对对象内容的读取和写入。

3.2.1 对象内容读取

JavaScript 中对象内容读取十分的简单,如果属性键为字符串,且该字符串中只包含英文字母和下划线的话,可以直接用 <obj>.<key> 来读取属性值。

const post = {
  title: '基本数据处理 · 对象字面量',
  serialNo: 2,
  parentBook: {
    title: '基于 JavaScript 开发灵活的数据应用',
    author: {
      name: '小问',
      title: '多领域开发者',
      domains: [ 'Web 开发', '大数据', '机器学习' ]
    }
  },
  
  content: '......'
}

console.log(post.title) //=> 基本数据处理 · 对象字面量
console.log(post.parentBook.author.name) //=> 小问

而当对象中所需要读取的目标属性键为数字、包含英文字母和下划线以外的字符串甚至是 Symbol 对象的时候,就需要使用 obj[key] 的形式来读取属性值了。

const obj = {
  1: 2,
  'a b c': 'd e f',
  [Symbol.for('foo')]: 'bar'
}

console.log(obj[1]) //=> 2
console.log(obj['a b c']) //=> d e f
console.log(obj[Symbol.for('foo')]) //=> bar

3.2.2 修改对象内容

虽然使用 const 语句所定义的对象是不能直接被替换的,但是其中的内容依然能被修改。

关于 constletvar 的故事,可以自行搜索,也可以参考笔者的《实战 ES2015》,其中有很详细的讲解。

在 JavaScript 中存在着“引用”和“值”的概念区别,当然这同样不是本书的讨论范围。简单地解释,就是对对象内容进行修改跟进行读取类似,只是在读取语句后面加上 = <new value> 即可。

const obj = {
  foo: 'bar',
  1: 2,
  'a b c': 'd e f',
  [Symbol.for('foo')]: 'bar'
}

obj.foo = 'rab'
obj[1] = 3
console.log(obj.foo) //=> rab
console.log(obj[1]) //=> 3

当然,当你需要为一个对象添加新的属性时,也是通过同样的方式添加属性。

const obj = {}

obj.foo = 'bar'
obj[1] = 2

但要非常注意的是,在一般情况下,无论是对对象进行添加、读取还是修改属性,都遵循着嵌套链完整的原则,具体如下例所示。

const outer = {
  inner: {}
}

outer.inner.foo = 'bar' // OK
outer.something.bar = 1 // Error!

小结

对象可以说是在 JavaScript 编程开发中最最重要的概念,懂得如何在最基础的知识上学会灵活使用,在后面的学习和开发中你会变得事半功倍。

习题

请用对象字面量描述自己,尽可能多地丰富对象属性内容,并注意其中的层级嵌套关系。