不区分大小写访问JavaScript属性?

Mat*_*att 61 javascript properties object

假设我有一个对象:

var obj = {
  foo:"bar",
  fizz:"buzz"
};
Run Code Online (Sandbox Code Playgroud)

我需要动态访问该对象的属性,如下所示:

var objSetter = function(prop,val){
  obj[prop] = val;
}
Run Code Online (Sandbox Code Playgroud)

没有问题,除了那些prop需要不区分大小写,如果属性名称被传递到函数中,比如说,Foo而不是foo.

那么如何在不考虑大小写的情况下通过名称指向对象的属性呢?我想尽可能避免迭代整个对象.

Ano*_*oop 24

将obj的所有属性与prop进行比较.

var objSetter = function(prop,val){
  prop = (prop + "").toLowerCase();
  for(var p in obj){
     if(obj.hasOwnProperty(p) && prop == (p+ "").toLowerCase()){
           obj[p] = val;
           break;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 不需要将`p`强制转换为字符串,ECMA-262将对象属性指定为字符串,任何不符合的用户代理或主机都会出现严重问题.也不需要`break`,你应该使用`return`. (14认同)
  • 谢谢.这肯定会奏效,但我希望避免迭代整个对象.我将编辑我的帖子以使其更清晰.再次感谢. (2认同)
  • 我在一个拥有超过 100 万个键的对象上尝试了这个,它的速度慢得令人无法忍受。更好的方法是使用代理对象(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)。或者,如果您的用例允许,只需将键以大写形式添加到字典中 (2认同)

Sho*_*use 17

试试这个:

var myObject = { "mIxeDCaSEKeY": "value" };

var searchKey = 'mixedCaseKey';
myObject[Object.keys(myObject).find(key => key.toLowerCase() === searchKey.toLowerCase())];
Run Code Online (Sandbox Code Playgroud)

您也可以使用小写提供searchKey.

如果你想要它作为一个功能:

/**
  * @param {Object} object
  * @param {string} key
  * @return {any} value
 */
function getParameterCaseInsensitive(object, key) {
  return object[Object.keys(object)
    .find(k => k.toLowerCase() === key.toLowerCase())
  ];
}
Run Code Online (Sandbox Code Playgroud)

如果无法找到该对象,那么它将返回undefined,就像正常一样.

如果您需要支持旧版浏览器,则可以使用filter:

function getParameterCaseInsensitive(object, key) {
  return object[Object.keys(object).filter(function(k) {
    return k.toLowerCase() === key.toLowerCase();
  })[0]];
}
Run Code Online (Sandbox Code Playgroud)

如果您需要更旧的支持,我建议使用Object.keys()Array.filter()的polyfill.


Mat*_*win 9

为此,我更喜欢将原型用于独立功能,只是为了易于使用和表现力.我不喜欢将对象汇集到函数中,如果我不需要的话.

此外,虽然接受的答案有效,但我想要一个更全面的解决方案来获取和设置,其行为与本机点表示法或括号表示法尽可能一样.

考虑到这一点,我创建了几个原型函数来设置/获取对象属性而不考虑大小写.添加到Object原型时,您必须记住要非常负责任.特别是在使用JQuery和其他库时.具有枚举设置为false的Object.defineProperty()专门用于避免与JQuery冲突.我也没有打扰任何表明它们不区分大小写的功能,但你当然可以.我喜欢简短的名字.

这是吸气剂:

Object.defineProperty(Object.prototype, "getProp", {
    value: function (prop) {
        var key,self = this;
        for (key in self) {
            if (key.toLowerCase() == prop.toLowerCase()) {
                return self[key];
            }
        }
    },
    //this keeps jquery happy
    enumerable: false
});
Run Code Online (Sandbox Code Playgroud)

这是二传手:

Object.defineProperty(Object.prototype, "setProp", {
    value: function (prop, val) {
        var key,self = this;
        var found = false;
        if (Object.keys(self).length > 0) {
            for (key in self) {
                if (key.toLowerCase() == prop.toLowerCase()) {
                    //set existing property
                    found = true;                        
                    self[key] = val;
                    break;
                }
            }
        }

        if (!found) {
            //if the property was not found, create it
            self[prop] = val;
        }  

        return val;
    },
    //this keeps jquery happy
    enumerable: false
});
Run Code Online (Sandbox Code Playgroud)

现在我们已经创建了这些函数,我们的代码非常干净简洁,只是起作用.

不区分大小写:

var obj = {foo: 'bar', camelCase: 'humpy'}

obj.getProp("FOO");          //returns 'bar'
obj.getProp("fOO");          //returns 'bar'
obj.getProp("CAMELCASE");    //returns 'humpy' 
obj.getProp("CamelCase");    //returns 'humpy'
Run Code Online (Sandbox Code Playgroud)

不区分大小写的设置:

var obj = {foo: 'bar', camelCase: 'humpy'}

obj.setProp('CAmelCasE', 'super humpy');     //sets prop 'camelCase' to 'super humpy'
obj.setProp('newProp', 'newval');      //creates prop 'newProp' and sets val to 'newval'  
obj.setProp('NewProp', 'anotherval');  //sets prop 'newProp' to 'anotherval'
Run Code Online (Sandbox Code Playgroud)

  • 当然,一旦有人执行 `obj.setProp("GETPROP")`,这就会失败 (2认同)

Rus*_*ord 6

还有另外一种变体已经呈现,它们将迭代推向Underscore/Lodash findKey函数:

var _ = require('underscore');
var getProp = function (obj, name) {
    var realName = _.findKey(obj, function (value, key) {
        return key.toLowerCase() === name.toLowerCase();
    });
    return obj[realName];
};
Run Code Online (Sandbox Code Playgroud)

例如:

var obj = { aa: 1, bB: 2, Cc: 3, DD: 4 };
getProp(obj, 'aa'); // 1
getProp(obj, 'AA'); // 1
getProp(obj, 'bb'); // 2
getProp(obj, 'BB'); // 2
getProp(obj, 'cc'); // 3
getProp(obj, 'CC'); // 3
getProp(obj, 'dd'); // 4
getProp(obj, 'DD'); // 4
getProp(obj, 'EE'); // undefined
Run Code Online (Sandbox Code Playgroud)

  • @ZachSmith这是O(n); 见[这里](https://github.com/jashkenas/underscore/blob/e944e0275abb3e1f366417ba8facb5754a7ad273/underscore.js#L1093-L1101). (2认同)