DEV Community

loading...
Cover image for Single keyword expressions in JavaScript

Single keyword expressions in JavaScript

jochemstoel profile image Jochem Stoel ・2 min read

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.

Discussion (5)

pic
Editor guide
Collapse
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Neat. Should maybe use Date.now()?

Collapse
jochemstoel profile image
Jochem Stoel Author

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 Author

You are right. Enumerable defaults to false. It needn't be included.

Collapse
Sloan, the sloth mascot
Comment deleted