Working on some project I noticed myself using the memoization pattern many times to create lazy evaluated properties. With ES5 a new way of implementing lazy attributes becomes available, preserving the interface of an attribute.

Motivation

Given the following example object containing a property obj.expensive :

var obj = { expensive : /* Some really expensive calculations */ }

Our goal is to only evaluate the expression for obj.expensive if it is really necessary. The most common way to achieve this is using a function and memoization.

var obj = { expensive : function expensive (){ if ( memoized . hasOwnProperty ( "value" )) { return expensive . value } expensive . value = /* Some really expensive calculations */ return expensive . value ; } }

This way the value is just calculated once at the time obj.expensive is actually used.

Improved Version

This is a lot of boilerplate, so let’s factor most things out into a function lazy .

function lazy ( init ) { return function memoized () { if ( memoized . hasOwnProperty ( "value" )) { return memoized . value } memoized . value = init . call ( this ); return memoized . value ; } } var obj = { expensive : lazy ( function () { return /* Some really expensive calculations */ }) }

Much better. But still the interface to the user of obj changes from obj.expensive to obj.expensive() .

The ES5 Way – Getters

Using getters the code can be improved even more in order to preserve the interface to the user.

function lazy ( init ) { return { enumerable : true , configurable : false , get : function memoized () { if ( memoized . hasOwnProperty ( "value" )) { return memoized . value } memoized . value = init . call ( this ); return memoized . value ; } } } var obj = Object . create ( Object . prototype , { expensive : lazy ( function () { return /* Some really expensive calculations */ }) }

You may have noticed, that property descriptors and Object.create are used to define the property. Since descriptors allow to specify additional meta information on the mutability and visibility of a property I try to use them when ever possible (and appropriate).

Off topic: Other property descriptor helpers

Here are just two of the helper functions I usually use to define property descriptors

function method ( fun ) { return { value : fun , configurable : false , enumerable : false }; } function property ( value ) { return { value : value , writable : true , enumerable : true } }

Using those an object definition can look like

var o = Object . create ( Object . prototype , { foo : property ( 42 ), expensive : lazy ( function () { return /* ... */ }), doFoo : method ( function ( arg ) { return this . foo + arg + this . expensive }) });

ES6 Arrow Functions

This even looks nicer using ES6 Arrow Functions