Search code examples
javascriptdefineproperty

How to make a property/method invokable or not?


I want to achieve this functionality:

  1. I have an object var obj = {};
  2. I have three properties on that obj, obj.zero & obj.one& obj.binaryString

    • obj.zero & obj.one are methods while obj.binaryString is a string

When I chain the properties, I want them to add their respective digit to the binaryString. So for example:

obj.one.zero.zero.one => makes obj.binaryString = 1001

obj.one.zero.one.one.zero => makes obj.binaryString = 10110

I have achieved the above functionality with this:

function Binary () {
    var obj = { binaryString: '' };

    Object.defineProperty(obj, 'zero', {
        get: function() {
            obj.binaryString += '0';
            return obj;
        }
    });

    Object.defineProperty(obj, 'one', {
        get: function() {
            obj.binaryString += '1';
            return obj;
        }
    });

    return obj;
}

var binary = new Binary();
binary.one.zero.zero.one  // => obj.binaryString becomes '1001'

Now I want to log out the completed binaryString, plus and additionalString which I have accomplished with the code below:

// placed inside Binary constructor function
Object.defineProperty(obj, 'log', {
    get: function() {
        return function(additionalString) {
            console.log(obj.binaryString + additionalString);
        };
    }
});

So with this current code I can do this:

binary.one.zero.one.zero.one.log(' is the answer');
// logs out `10101 is the answer`

What I want to do is get rid of the log and make the one and zero methods invokable or not so I can achieve this functionality:

binary.one.one.zero.one(' is the result')
// => logs out `1101 is the result`

How can I do this?

I believe it would be similar functionality to how Chalk works:

chalk.blue.bold('Hello world!');
// `blue` is not invoked here but it adds the color blue to the style

chalk.blue('Hello world!');
// `blue` IS invoked here.  It adds blue to the style and returns the stylized string

Solution

  • Just Make the obj as function , and print what ever you want .

    function Binary () {
        var obj = function(msg){ console.log(msg+this.binaryString ) };
        obj.binaryString = ''
    
        Object.defineProperty(obj, 'zero', {
            get: function() {
                obj.binaryString += '0';
                return obj;
            }
        });
    
        Object.defineProperty(obj, 'one', {
            get: function() {
                obj.binaryString += '1';
                return obj;
            }
        });
    
        return obj;
    }
    
    var binary = new Binary();
    binary.one.zero.zero.one.zero(" is the result ")