为什么我要说 JavaScript 对象字面量很酷?

625 查看

ECMAScript 2015 之前,JavaScript 里的对象字面量(也叫对象初始化器)功能很弱。它只能定义两种属性:

  • 普通键/值对 { name1: value }
  • Getters { get name(){..} } 以及 setters { set name(val){..} },用来设置和获取需要计算的值。

令人心痛地,对象字面量的所有用法只用一个简单的例子就能囊括:

Try in JS Bin

JavaScript 是一个基于原型的语言,因此一切皆是对象。当涉及到对象创建、结构和访问原型时,语言必须提供简单的结构。

定义一个对象并设置它的原型是一个常见的任务。我总觉得设置原型应该被对象字面量直接支持,使用单一的语法。

不幸的是,字面量的局限性使得它没有直接的解决方案。你不得不使用Object.create() 来结合对象字面量和设置原型:

Try in JS Bin

在我看来,这是一个不舒服的解决方案。JavaScript 是基于原型的,为什么从原型创建一个对象那么麻烦?

幸运地是,JavaScript 在改变。比较令人沮丧的许多问题在 JavaScript 中正在被一步一步地解决。

这篇文章解释 ES2015 是如何解决上面所说的问题以及改进对象字面量以获得额外的好处::

  • 在对象构造的过程中设置原型
  • 速记方法定义
  • 调用父类方法
  • 计算属性名称

同时,让我们看看未来,了解最新的提案(stage 2):对象的 rest 属性和属性展开操作符。

t012606848a780583cd

1. 在对象构造时设置原型

如你已经知道得,其中一个访问一个已存在对象的原型的方法是使用 getter 属性__proto__

Try in JS Bin

myObject.__proto__ 返回 myObject 的原型对象。

好消息是 ES2015 允许使用 字面量 __proto__ 作为属性名来设置对象字面量的原型 { __proto__: protoObject }

让我们用 __proto__ 重写一下上面那个例子,让它看起来好一点:

Try in JS Bin

myNumbers 对象使用原型 myProto 创建,这可以通过特殊属性 __proto__ 实现。

这个对象通过简单的语句创建,而不需要额外的函数例如 Object.create()

如你所见,使用 __proto__ 是简单的。我偏爱简单直接的解决方案。

有点说跑题了,回到主题来。我认为获得简单和可靠的解决方案需要通过大量的设计和实践。如果一个解决方案是简单的,你可能认为它同样也很容易被设计出来,然而事实并不是这样:

  • 让它变得简单明了的过程是复杂的
  • 让它变得复杂和难以理解却很容易

如果某个东西看起来太复杂或者用起来不舒服,很可能它的设计者考虑不周。

元芳,你怎么看?(欢迎在文章底部发表评论参与讨论)

2.1 使用 __proto__ 的特例

尽管 __proto__ 看似简单,却有一些特殊的场景你需要格外注意。

t0104a3811cb73f6010

在对象字面量中 __proto__ 只允许使用一次。多次是用的话 JavaScript 会抛出异常:

Try in JS Bin