DEV Community

Discussion on: I.can.has("cheezeburger")

Collapse
 
omnoms profile image
Marko V • Edited

For the sake of brevity, here's a class-style variation

const I = (function () {
    function I(obj) {
        this._obj = obj;
        this._negate = false;
    }
    function everyProp(currObj) {
        return function(prop) {
            if( typeof currObj === "undefined" || currObj === null || !(prop in currObj))
                return false;
            currObj = currObj[prop];
            return true;
        };
    }
    I.prototype.has = function(key) {
        var tObj = this._obj;
        const returnObj = key.split(".").every(everyProp(tObj));
        if (this._negate) return !returnObj;
        return returnObj;
    };
    return I;
}());
Object.defineProperty(I.prototype, 'can', { get: function() { return this; } });
Object.defineProperty(I.prototype, 'is', { get: function() { return this; } });
Object.defineProperty(I.prototype, 'not', { get: function() { this._negate = !this._negate; return this; } });
Object.defineProperty(I.prototype, 'undef', { get: function() { 
    if(this._negate) return typeof this._obj !== "undefined";
    return typeof this._obj === "undefined"; 
}});
Object.defineProperty(I.prototype, 'null', { get: function() { 
    if(this._negate) return this._obj !== null;
    return this._obj === null; 
}});

var food = { hamburger: true, bun: { top: "wholemeal"} } ;
console.log(new I(food).can.not.has("bun.top"));
console.log(new I(food).can.has("cheezeburger"));

Now if you still want to hide the new-ing up of an instance, you can wrap it.

If you name your IIFE class to something like "myutil" and then make the global function "I" return a new instance of myutil using the same provided parameters as the function accepts.

// update all I.prototype to myutil.prototype
const myutil = (function () {
    function myutil(obj) {
        this._obj = obj;
        this._negate = false;
    }
   ...
   return myutil;
}())
// Update all Object.defineProperty calls on I.prototype to myutil.prototype
...

function I(obj) {
    return new myutil(obj);
}