Like I did in previous articles on the series, I would love to point out that you should probably set up Babel and follow along the examples with either a REPL or the babel-node
CLI and a file. That’ll make it so much easier for you to internalize the concepts discussed in the series. If you aren’t the “install things on my computer” kind of human, you might prefer to hop on CodePen and then click on the gear icon for JavaScript – they have a Babel preprocessor which makes trying out ES6 a breeze.
Onto the new stuff!
Property Value Shorthands
Whenever you find yourself assigning a property value that matches a property name, you can omit the property value, it’s implicit in ES6.
var foo = 'bar'
var baz = { foo }
console.log(baz.foo)
// <- 'bar'
In the snippet shown below I re-implemented part of localStorage
in memory as a polyfill. It displays a pattern that I’ve followed countless times in my code.
var ms = {}
function getItem (key) {
return key in ms ? ms[key] : null
}
function setItem (key, value) {
ms[key] = value
}
function clear () {
ms = {}
}
module.exports = {
getItem: getItem,
setItem: setItem,
clear: clear
}
The reasons why – most often – I don’t place functions directly on an object definition are several.
- Less indentation needed
- Public API stands out
- Harder to tightly couple methods
- Easier to reason about
With ES6, we can throw another bullet into that list, and that’s that the export can be even easier using property value shorthands. You can omit the property value if it matches the property name. The module.exports
from the code above thus becomes:
module.exports = { getItem, setItem, clear }
So good!
Computed Property Names
We already covered computed property names briefly in the destructuring article. This was a very common thing to do for me:
var foo = 'bar'
var baz = {}
baz[foo] = 'ponyfoo'
console.log(baz)
// <- { bar: 'ponyfoo' }
Computed property names allow you to write an expression wrapped in square brackets instead of the regular property name. Whatever the expression evaluates to will become the property name.
var foo = 'bar'
var baz = { [foo]: 'ponyfoo' }
console.log(baz)
// <- { bar: 'ponyfoo' }
One limitation of computed property names is that you won’t be able to use the shorthand expression with it. I presume this is because shorthand expression is meant to be simple, compile-time sugar.
var foo = 'bar'
var bar = 'ponyfoo'
var baz = { [foo] }
console.log(baz)
// <- SyntaxError
That being said, I believe this to be the most common use case. Here our code is simpler because we don’t have to spend three steps in allocating a foo
variable, assigning to foo[type]
, and returning foo
. Instead we can do all three in a single statement.
function getModel (type) {
return {
[type]: {
message: 'hello, this is doge',
date: new Date()
}
}
}
Neat. What else?
Method Definitions
Typically in ES5 you declare methods on an object like so:
var foo = {
bar: function (baz) {
}
}
While getters and setters have a syntax like this, where there’s no need for the function
keyword. It’s just inferred from context.
var cart = {
_wheels: 4,
get wheels () {
return this._wheels
},
set wheels (value) {
if (value < this._wheels) {
throw new Error('hey, come back here!')
}
this._wheels = value
}
}
Starting in ES6, you can declare regular methods with a similar syntax, only difference is it’s not prefixed by get
or set
.
var cart = {
_wheels: 4,
get wheels () {
return this._wheels
},
set wheels (value) {
if (value < this._wheels) {
throw new Error('hey, come back here!')
}
this._wheels = value
},
dismantle () {
this._wheels = 0
console.warn(`you're all going to pay for this!`)
}
}
I think it’s nice that methods converged together with getters and setter. I for one don’t use this syntax a lot because I like to name my functions and decouple them from their host objects as I explained in the shorthand section. However, it’s still useful in some situations and definitely useful when declaring “classes” – if you’re into that sort of thing.
Comments