DEV Community

Cover image for Single keyword expressions in JavaScript
Jochem Stoel
Jochem Stoel

Posted on

Single keyword expressions in JavaScript

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()
})
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

Output

0
1
2
3
4
5
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Output

0
1
2
3
...
...
...
997
998
999
process took 1848 milliseconds.
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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. */
Enter fullscreen mode Exit fullscreen mode
start 
setTimeout(() => end, 5000) /* this will exit in 5000 milliseconds. */
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
bennypowers profile image
Benny Powers ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฆ

Neat. Should maybe use Date.now()?

Collapse
 
jochemstoel profile image
Jochem Stoel

These are details distracting from the purpose of this article.

Collapse
 
bgadrian profile image
Adrian B.G.

Nice examples, for sure is an underused JS feature.

One comment, isnt enumerable default false?

Collapse
 
jochemstoel profile image
Jochem Stoel

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.