4

I am trying to make an Object who, when I search for a property, performs a "look-up" of that property case-insensitively.

var x = new CaseInsensitiveObject();

x.firstProperty = "Hello!";

alert(x.firstproperty); //alerts Hello!

I've tried using Object.defineProperty() for this, yet it requires the string literal for the property as a parameter (Object.defineProperties() will have the same problem if you think about it).

Is there a way that I can generic set the getter for all object properties of an object without providing the key name? i.e:

Object.defineAllProperties(obj, {
    get: function(prop)
    {
        if(!prop.toLowerCase && prop.toString)
            prop = prop.toString();
        if(prop.toLowerCase)
            prop = prop.toLowerCase();
        return this[prop];
    }
});

If not all properties, how could I set even one property of an Object to be case insensitive?!

NOTE:

I understand that extending the Object.prototype is generally a bad thing to do, but I have my reasons. I need a quick fix due to some database changes. The eventual fix will take days to do, and I need running software for QA to test against until then. This prototype method will make everything work while I make all of the necessary changes, and this method WILL NOT be put into any production environment. So, if you plan on shooting me down and yelling at me for even thinking about doing this, I'm not listening.

Thanks everybody!

WebWanderer
  • 10,380
  • 3
  • 32
  • 51
  • I've checked many other post which are similar to my answer but don't really touch on it, like these (which this is not a duplicate of!!!): [Case Insensitive Mapping](http://stackoverflow.com/questions/17556948/case-insensitive-property-mapping), [Set Protoype For All Object Properties](http://stackoverflow.com/questions/26662202/set-prototype-for-all-object-properties), and many more – WebWanderer Jun 19 '15 at 18:34
  • 3
    You could write a whole bunch of setter/getters for every capitalization permutation of a property name. Alternatively, you could use a [`Proxy` object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) in environments that support them. – apsillers Jun 19 '15 at 18:36
  • Haha, I think that making a getter and setter for all permeation of a key would be a little intensive. Good shot though @apsillers . `Proxy` would work, but unfortunately, its ECMA6. Can't use it. – WebWanderer Jun 19 '15 at 18:40
  • Your requirement sounds like you would only need one or two alternative spellings, not *all* of them? I think you just should do it manually. – Bergi Jun 19 '15 at 18:56
  • True @Bergi, I do only have two alternative spellings. apsillers comment solves my problem, but does not fully answer my question. – WebWanderer Jun 19 '15 at 19:16

1 Answers1

0

So, after following @apsillers comment, I did solve my problem (I only needed support for lower-case and camel-case. This is not what I would consider ideal and does not actually answer my question of making a case-insensitive Object property, but I should share:

function makeCaseInsensitiveObject(obj)
{
    var keys;

    function PropertyScope(iObj, key, val)
    {
        var value = val;

        var _get = function()
        {
            return value;
        };

        var _set = function(v)
        {
            value = v;
        };

        Object.defineProperty(iObj, key, {
            get: _get,
            set: _set
        });

        Object.defineProperty(iObj, key.toLowerCase(), {
            get: _get,
            set: _set
        });
    };

    if(Object.keys)
        keys = Object.keys(obj);
    else
        keys = getObjectKeys(obj);

    for(var i = 0; i < keys.length; i++)
    {
        if(typeof keys[i] === 'string')
        {
            PropertyScope(obj, keys[i], obj[keys[i]]);
        }
    }

    return obj;
};

Be aware that the case-insensitivity here will only apply to existing object properties, not any new ones.

Thanks everybody!

WebWanderer
  • 10,380
  • 3
  • 32
  • 51
  • 1
    I was writing up an answer, but it was basically this. I'll just leave the one purely-informative part here: The general category of behavior encompassed by, "Perform arbitrary decision-making based on the property name used in property access," is only possibly through proxies. Without proxy objects, it is merely possibly to assign a decision-making function (i.e., a setter/getter) to any given property name. In other words, if you don't have proxies, you must know the property name in advance; there is no other option. – apsillers Jun 19 '15 at 19:27
  • Dang! Well, that sucks, but thanks @apsillers ! Can't wait for ECMA6! – WebWanderer Jun 19 '15 at 19:49