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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12484386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 10:30:16  来源:igfitidea点击:

Access JavaScript property case-insensitively?

javascriptobjectproperties

提问by Matt Cashatt

Assume I have an object:

假设我有一个对象:

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

I need to access a property of that object dynamically like so:

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

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

No problems there, except for that propneeds to be case insensitive in case the property name is passed into the function as, say, Fooinstead of foo.

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

So how can I point to an object's property by name without regard to case? I would like to avoid iterating the entire object if possible.

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

采纳答案by Anoop

Compare all the properties of obj with prop.

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

回答by ShortFuse

Try this:

尝试这个:

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

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

You can alternatively already provide the searchKey in lowercase.

您也可以提供小写的 searchKey。

If you want it as a function:

如果你想把它作为一个函数:

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

If the object can't be found, then it'll return undefined, just like normal.

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

If you need to support older browsers, then you can use filterinstead:

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

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

I suggest using the polyfills for Object.keys()and Array.filter()if you need even older support.

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

回答by Matt Goodwin

For this, I prefer using the prototype over a standalone function just for ease of use and expressiveness. I just don't like funneling objects into functions if I don't have to.

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

Also, while the accepted answer works, I wanted a more comprehensive solution for both getting and setting that would behave as much like the native dot notation or bracket notation as possible.

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

With that in mind, I created a couple prototype functions for setting/getting an object property without regard to case. You have to remember to be VERYresponsible when adding to the Object prototype. Especially when using JQuery and other libraries. Object.defineProperty() with enumerable set to false was used specifically to avoid conflict with JQuery. I also didn't bother naming the functions anything that indicates they are case-insensitive, but you certainly could. I like shorter names.

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

Here's the getter:

这是吸气剂:

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

Here's the setter:

这是二传手:

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

Now that we've created those functions, our code is super clean and concise and just works.

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

Case-insensitive getting:

不区分大小写的获取:

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'

Case-insensitive setting:

不区分大小写的设置:

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'

回答by Rusty Shackleford

Yet another variation on those already presented which pushes the iteration down into the Underscore/Lodash findKeyfunction:

已经提出的另一种变体将迭代推入 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];
};

For example:

例如:

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

回答by Claudio Redi

You could do this in order to "normalize" prop

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

 var normalizedProp = prop.toLowerCase();
 obj[normalizedProp] = val;

回答by KaiOsmon

why would we do it that complicated when we simply can make it all lower case:

当我们可以简单地将其全部设为小写时,为什么我们要这样做那么复杂:

    var your_object = { 
"chickago" : 'hi' ,
 "detroit" : 'word', 
 "atlanta" : 'get r dun',     
GetName: function (status) {
        return this[status].name;
    } };

to call it:your_object.GetName(your_var.toLowerCase());

调用它:your_object.GetName(your_var.toLowerCase());

回答by Enrique Alamo

It seems to me like a good candidate for Proxy with traps to convert string keys to either upper case or lower case and behaving like a regular object. This works with either notation: dots or braquets

在我看来,它是带有陷阱的 Proxy 的一个很好的候选者,可以将字符串键转换为大写或小写,并且表现得像一个普通对象。这适用于任何一种符号:点或括号

Here is the code:

这是代码:

'use strict';

function noCasePropObj(obj)
{
 var handler =
 {
  get: function(target, key)
   {
    //console.log("key: " + key.toString());
    if (typeof key == "string")
    {
     var uKey = key.toUpperCase();

     if ((key != uKey) && (key in target))
      return target[key];
     return target[uKey];
    }
    return target[key];
   },
  set: function(target, key, value)
   {
    if (typeof key == "string")
    {
     var uKey = key.toUpperCase();

     if ((key != uKey) && (key in target))
      target[key] = value;
     target[uKey] = value;
    }
    else
     target[key] = value;
   },
  deleteProperty: function(target, key)
   {
    if (typeof key == "string")
    {
     var uKey = key.toUpperCase();

     if ((key != uKey) && (key in target))
      delete target[key];
     if (uKey in target)
      delete target[uKey];
    }
    else
     delete target[key];
   },
 };
 function checkAtomic(value)
 {
  if (typeof value == "object")
   return new noCasePropObj(value); // recursive call only for Objects
  return value;
 }

 var newObj;

 if (typeof obj == "object")
 {
  newObj = new Proxy({}, handler);
        // traverse the Original object converting string keys to upper case
  for (var key in obj)
  {
   if (typeof key == "string")
   {
    var objKey = key.toUpperCase();

    if (!(key in newObj))
     newObj[objKey] = checkAtomic(obj[key]);
   }
  }
 }
 else if (Array.isArray(obj))
 {
        // in an array of objects convert to upper case string keys within each row
  newObj = new Array();
  for (var i = 0; i < obj.length; i++)
   newObj[i] = checkAtomic(obj[i]);
 }
 return newObj; // object with upper cased keys
}

// Use Sample:
var b = {Name: "Enrique", last: "Alamo", AdDrEsS: {Street: "1233 Main Street", CITY: "Somewhere", zip: 33333}};
console.log("Original: " + JSON.stringify(b));  // Original: {"Name":"Enrique","last":"Alamo","AdDrEsS":{"Street":"1233 Main Street","CITY":"Somewhere","zip":33333}}
var t = noCasePropObj(b);
console.log(JSON.stringify(t)); // {"NAME":"Enrique","LAST":"Alamo","ADDRESS":{"STREET":"1233 Main Street","CITY":"Somewhere","ZIP":33333}}
console.log('.NaMe:' + t.NaMe); // .NaMe:Enrique
console.log('["naME"]:' + t["naME"]); // ["naME"]:Enrique
console.log('.ADDreSS["CitY"]:' + t.ADDreSS["CitY"]); // .ADDreSS["CitY"]:Somewhere
console.log('check:' + JSON.stringify(Object.getOwnPropertyNames(t))); // check:["NAME","LAST","ADDRESS"]
console.log('check2:' + JSON.stringify(Object.getOwnPropertyNames(t['AddresS']))); // check2:["STREET","CITY","ZIP"]

回答by nilloc

This answer requires ES6.

这个答案需要 ES6。

const x = {'X-Total-Count':10};
console.log(x[Object.keys(x).reduce(key=>{return key.match(/x-total-count/i)})]);

回答by Yaron Pdut

const getPropertyNoCase = (obj, prop) => obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];

or

或者

const getPropertyNoCase = (obj, prop) => {
    const lowerProp = prop.toLowerCase(obj[Object.keys(obj).find(key => key.toLowerCase() === prop.toLowerCase() )];
}

回答by JerryGoyal

Another simple way:

另一种简单的方法:

function getVal(obj, prop){
var val;
  prop = (prop + "").toLowerCase();
  for(var p in obj){
     if(obj.hasOwnProperty(p) && prop == (p+ "").toLowerCase()){
           val = obj[p]
           break;
      }
   }
   return val;
}

Use it like this:

像这样使用它:

var obj = {
  foo:"bar",
  fizz:"buzz"
};
    getVal(obj,"FoO") -> returns "bar"