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

IT技术 javascript object properties
2021-01-16 21:20:23

假设我有一个对象:

var obj = {
  foo:"bar",
  fizz:"buzz"
};

我需要像这样动态访问该对象的属性:

var objSetter = function(prop,val){
  obj[prop] = val;
}

没有问题,除了prop需要不区分大小写,以防将属性名称传递给函数,例如,Foo而不是foo.

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

6个回答

试试这个:

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

var searchKey = 'mixedCaseKey';
myObject[Object.keys(myObject).find(key => key.toLowerCase() === searchKey.toLowerCase())];

您也可以提供小写的 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())
  ];
}

如果找不到对象,则它会像平常一样返回 undefined。

如果您需要支持较旧的浏览器,则可以filter改用:

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

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

我很好奇,文档注释样式来自什么。然后我找到了jsdoc.app/about-getting-started.html
2021-03-27 21:20:23
TypeScript 还将本机读取 JSDocs 并执行类型检查。它内置于 VSCode 中,让生活更轻松。
2021-04-01 21:20:23

将 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;
      }
   }
}
我在一个拥有超过 100 万个键的对象上尝试了这个,它的速度慢得令人无法忍受。更好的方法是使用代理对象(developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...)。或者,如果您的用例允许,只需将键以大写形式添加到字典中
2021-03-19 21:20:23
谢谢 Shusl,看起来迭代是我唯一的选择。另外,你能告诉我这+ ""是做什么用的吗?这只是用于字符串转换吗?
2021-03-23 21:20:23
确保 toLowerCase 应用于字符串。例如。(1 + "") 将 1 转换为 "1"。
2021-03-23 21:20:23
无需强制转换p为字符串,ECMA-262 将对象属性指定为字符串,任何不合规的用户代理或主机都会出现严重问题。也没有必要break,你应该使用return.
2021-04-04 21:20:23
谢谢。这肯定会起作用,但我希望避免迭代整个对象。我将编辑我的帖子以使其更清楚。再次感谢。
2021-04-11 21:20:23

为此,我更喜欢使用原型而不是独立函数,只是为了便于使用和表达。如果没有必要,我只是不喜欢将对象汇集到函数中。

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

考虑到这一点,我创建了几个原型函数来设置/获取对象属性而不考虑大小写。在添加到对象原型时,您必须记住要非常负责。特别是在使用 JQuery 和其他库时。将 enumerable 设置为 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
});

这是二传手:

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

现在我们已经创建了这些函数,我们的代码非常干净简洁并且可以正常工作。

不区分大小写的获取:

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'

不区分大小写的设置:

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'
当然,一旦有人这样做,这将失败得可怕 obj.setProp("GETPROP")
2021-03-21 21:20:23

已经提出的另一种变体将迭代推入 Underscore/LodashfindKey函数:

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

例如:

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
@ZachSmith 是 O(n); 看到这里
2021-03-18 21:20:23
underscore图书馆如何实现这一点?即我正在寻找一种不涉及对某些对象的键进行线性搜索的方法
2021-04-11 21:20:23

您可以这样做以“正常化” prop

 var normalizedProp = prop.toLowerCase();
 obj[normalizedProp] = val;
谢谢。我知道如何转换prop为小写,但是如果我不能保证实际的属性名称都是小写怎么办?也许我错过了什么?
2021-03-16 21:20:23
否决的原因:这并没有回答它假设的问题,就像@RobG 的回答一样,该属性是小写的。
2021-03-23 21:20:23
@MatthewPatrickCashatt 你没有错过任何东西:没有什么可错过的——因为这里的语言没有任何帮助:)
2021-04-10 21:20:23