/** * Note this version works a little differently. Where the other * versions do each operation as they happen, this version * waits until `value` is called before evaluating the entire expression. * This means this version will find the correct "mathematical" answer (as a single equation). **/ // map method names to related operator const methodToOperator = Object.freeze({ add: '+', subtract: '-', multiply: '*', divide: '/' }); // single get handler for known methods const handlers = { get( target, prop, receiver ) { if ( methodToOperator.hasOwnProperty( prop )) { const operator = methodToOperator[ prop ]; return function( m ) { target.eq += ` ${ operator } ${ m }`; // builds an equation target.n = eval( `${ target.n } ${ operator } ${ m }` ); // calculate as you go return receiver; } } if ( prop === 'value' ) { return function() { // console.log( `curr n: ${ target.n }\ncurr eq: ${ target.eq }` ); return eval( target.eq ); }; } } }; function given( n ) { return new Proxy({ n, eq: `${ n }` }, handlers ); }