copyright autobind autobind export default function autobind ( ) { return function ( ... args ) { if ( args . length === 1 ) { return boundClass ( args [ 0 ] ) ; } else { return boundMethod ( args [ 0 ] , args [ 1 ] , args [ 2 ] ) ; } } ; } /**
 * Use boundMethod to bind all methods on the target.prototype
 */ function boundClass ( target ) { let keys ; if ( typeof Reflect !== 'undefined' && typeof Reflect . ownKeys === 'function' ) { keys = Reflect . ownKeys ( target . prototype ) ; } else { keys = Object . getOwnPropertyNames ( target . prototype ) ; if ( typeof Object . getOwnPropertySymbols === 'function' ) { keys = keys . concat ( Object . getOwnPropertySymbols ( target . prototype ) ) ; } } keys . forEach ( key => { if ( key === 'constructor' ) { return ; } let descriptor = Object . getOwnPropertyDescriptor ( target . prototype , key ) ; if ( typeof descriptor . value === 'function' ) { Object . defineProperty ( target . prototype , key , boundMethod ( target , key , descriptor ) ) ; } } ) ; return target ; } /**
 * Return a descriptor removing the value and returning a getter
 * The getter will return a .bind version of the function
 * and memoize the result against a symbol on the instance
 */ function boundMethod ( target , key , descriptor ) { let fn = descriptor . value ; if ( typeof fn !== 'function' ) { throw new Error ( `@autobind decorator can only be applied to methods not: ${ typeof fn }` ) ; } let definingProperty = false ; return { configurable : true , get ( ) { if ( definingProperty || this === target . prototype || this . hasOwnProperty ( key ) ) { return this . hasOwnProperty ( key ) ? this [ key ] : fn ; } let boundFn = fn . bind ( this ) ; definingProperty = true ; Object . defineProperty ( this , key , { value : boundFn , configurable : true , writable : true , } ) ; definingProperty = false ; return boundFn ; } , } ; }