【问题标题】:Object Prototype: Case Insensitive Getter On All Properties对象原型:所有属性上不区分大小写的 Getter
【发布时间】:2015-06-20 03:20:13
【问题描述】:

我正在尝试创建一个Object,当我搜索属性时,它会不区分大小写地执行该属性的“查找”。

var x = new CaseInsensitiveObject();

x.firstProperty = "Hello!";

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

我尝试过为此使用Object.defineProperty(),但它需要属性的字符串文字作为参数(如果您考虑一下Object.defineProperties() 也会遇到同样的问题)

有没有一种方法可以为对象的所有对象属性通用设置getter 而无需提供键名?即:

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

如果不是所有属性,我如何将Object一个属性设置为不区分大小写?!

注意:

我知道扩展Object.prototype 通常是一件坏事,但我有我的理由。由于一些数据库更改,我需要快速修复。最终的修复需要几天的时间,我需要运行软件供 QA 进行测试,直到那时。当我进行所有必要的更改时,此原型方法将使一切正常,并且此方法不会被放入任何生产环境中。所以,如果你打算把我打倒,甚至因为我考虑这样做而对我大喊大叫,我不听。

谢谢大家!

【问题讨论】:

  • 我检查了许多其他与我的答案相似但并没有真正触及它的帖子,比如这些(这不是重复的!!!):Case Insensitive Mapping,@ 987654322@,还有更多
  • 您可以为属性名称的每个大写排列编写一大堆 setter/getter。或者,您可以在支持它们的环境中使用 Proxy object
  • 哈哈,我认为为键的所有渗透制作 getter 和 setter 会有点密集。虽然@apsillers 拍得不错。 Proxy 可以,但不幸的是,它的 ECMA6。无法使用。
  • 您的要求听起来好像只需要一两个替代拼写,而不是全部?我认为你应该手动完成。
  • True @Bergi,我只有两个替代拼写。 apsillers 的评论解决了我的问题,但没有完全回答我的问题。

标签: javascript prototype


【解决方案1】:

所以,在关注@apsillers 评论之后,我确实解决了我的问题(我只需要支持小写和驼峰式大小写。这不是我认为理想的,实际上并没有回答我制作案例的问题 -不敏感的 Object 属性,但我应该分享:

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;
};

请注意,此处不区分大小写仅适用于现有对象属性,而不适用于任何新属性。

谢谢大家!

【讨论】:

  • 我正在写一个答案,但基本上就是这样。我将在这里留下一个纯粹提供信息的部分:“根据属性访问中使用的属性名称执行任意决策”所包含的一般行为类别仅可能通过代理。如果没有代理对象,则只能将决策功能(即 setter/getter)分配给任何给定的属性名称。换句话说,如果你没有代理,你必须提前知道属性名;没有其他选择。
  • 该死!好吧,这很糟糕,但感谢@apsillers!等不及 ECMA6 了!
猜你喜欢
  • 2011-01-16
  • 2011-08-05
  • 1970-01-01
  • 2012-06-27
  • 2020-09-06
  • 1970-01-01
  • 2012-07-15
相关资源
最近更新 更多