start . me .
Directory path . web .

HTML Document File : optionally-callable.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>optionally-callable</title>
</head>
<body>

<h1>optionally callable</h1>

tests: <br>
<pre id="writeOut"></pre>

TODO: try nesting them!

<script>
var $side = 50

var buttonClassStyle = {
    color: "red" ,
    width: _ => $side , height: _ => $side ,
    padding: optionallyCallable({ right:10, bottom:10 }) ,
    heightCompound: _ => ( _.height + _.padding.bottom ) ,
}

write("previous usage:")
write( buttonClassStyle.width() )
write( buttonClassStyle.color )

buttonClassStyle = optionallyCallable(buttonClassStyle)

function optionallyCallable(objectToProxy) {
    var proxy
    var handlerOptionallyCallable = {
        // handle access
        get(target, accessedPropertyName, receiver) {
            return typeof target[accessedPropertyName] === 'function' ?
                target[accessedPropertyName] ( proxy /* same */ )
                : target[accessedPropertyName]
        },
    }
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
    proxy = new Proxy(objectToProxy, handlerOptionallyCallable)
    return proxy
}

function write(text){
    writeOut.textContent += text + "\n"
}

// tests

write("successive usage:")
write( buttonClassStyle.width )
write( buttonClassStyle.color )

//write( ++buttonClassStyle.width ) // not well supported, you can mutate $side


write("advanced usage:")
// still you can assign functions ...
buttonClassStyle.widthCompound= (same)=> ( same.width + same.padding.right )

// ... and they work with successive usage way (no parenthesis for "function calls")
write( buttonClassStyle.widthCompound )

write( "also .heightCompound" )
write( buttonClassStyle.heightCompound )

write( "contained functions (still possible)" )
buttonClassStyle.sum = _=> (function sum(a,b){ return a+b }) // optionally use first argument "_"

write( buttonClassStyle.sum(11,22) )
</script>

<script src="/web/show-source.js"></script>

</body>
</html>