Many of you are familiar with this. To those who are not this is a brief introduction to ummm single keyword expressions in JavaScript for lack of a better term. I sometimes get questions. If this does in fact have a name then by all means correct me.
The practice of defining (usually innumerable and read-only) global properties with a getter to reference them later with a single keyword statement. Look:
Object.defineProperty(global, 'exit', {
enumerable: false, /* this means it will not show up when iterating the 'global' object keys */
get: () => process.exit()
})
When we access exit in our script, it calls the getter function which will exit. Try it yourself!
/* i refuse to explain this part */
for(let i = 0; i < 10; i++) {
if(i > 5) {
exit;
}
console.log(i)
}
Output
0
1
2
3
4
5
Observe the following code that defines two global innumerable identifiers with a getter to calculate the script execution time.
Object.defineProperty(global, 'start', {
enumerable: false,
get: () => {
this.startTime = new Date().getTime()
}
}) /* when we reference 'start', store the current time in milliseconds in 'startTime' */
Object.defineProperty(global, 'end', {
enumerable: false,
get: () => {
let now = new Date().getTime()
let difference = now - this.startTime
console.log(`process took ${difference} milliseconds.`)
process.exit()
}
}) /* when we reference 'end', log the difference between now and 'startTime' then exit */
start;
for(i = 0; i < 1000; i++) {
console.log(i)
}
end;
Output
0
1
2
3
...
...
...
997
998
999
process took 1848 milliseconds.
Things
The this.startTime property in the example above is not globally accessible. If you console log this inside the getter function(s) you get an object with only 1 property startTime.
/* startTime, this.startTime, global.startTime, start.startTime do not exist */
start;
for(i = 0; i < 1000; i++) { /* ... */ }
end;
Because we are talking ECMAScript, the start and end references in the example do not require a semi-colon. Some developers prefer it, others go to war.
Understand that just referencing a property will already invoke the getter.
start
setTimeout(end, 5000) /* this will exit immediately. */
start
setTimeout(() => end, 5000) /* this will exit in 5000 milliseconds. */
In stead of providing a few more complex examples I will stop here and would like you to think of some and share them with us in the comment section. Thank you for reading.
Top comments (5)
Neat. Should maybe use Date.now()?
These are details distracting from the purpose of this article.
Nice examples, for sure is an underused JS feature.
One comment, isnt enumerable default false?
You are right. Enumerable defaults to false. It needn't be included.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.