就个人而言,我会使用:
let objectKeysToLowerCase = function (origObj) {
return Object.keys(origObj).reduce(function (newObj, key) {
let val = origObj[key];
let newVal = (typeof val === 'object') ? objectKeysToLowerCase(val) : val;
newObj[key.toLowerCase()] = newVal;
return newObj;
}, {});
}
它简洁,可重复处理嵌套对象并返回新对象,而不是修改原始对象。
在我有限的本地测试中,此功能比当前列出的其他递归解决方案(一旦固定)要快。我很想将其与其他产品进行基准测试,但jsperf目前无法使用(???)。
它也是用ES5.1编写的,因此根据MDN上的文档,它应该可以在FF 4 +,Chrome 5 +,IE 9.0 +,Opera 12 +,Safari 5+(因此,几乎所有功能)中使用。
Vanilla JS获胜。
我不会太担心所有这一切的垃圾收集方面。一旦所有对旧对象的引用被销毁,它将是GC的,但新对象基本上仍将引用其所有属性,因此它们不会。
所有函数,数组或RegExp将通过引用“复制”。就内存而言,由于大多数(全部?)现代JS引擎都使用用户字符串interning,因此即使是String也不会被此过程复制。我认为只剩下构成原始结构的数字,布尔值和对象需要进行GC处理。
请注意,如果原始文件具有多个具有相同小写表示形式的属性,则此过程(的所有实现)将丢失值。即:
let myObj = { xx: 'There', xX: 'can be', Xx: 'only', XX: 'one!' };
console.log(myObj);
let newObj = objectKeysToLowerCase(myObj);
console.log(newObj);
当然,有时候这正是您想要的。
更新2018-07-17
少数人注意到原始函数不适用于数组。这是扩展的,更具弹性的版本。它可以通过数组正确地重现,并且在初始值是数组或简单值的情况下可以工作:
let objectKeysToLowerCase = function (input) {
if (typeof input !== 'object') return input;
if (Array.isArray(input)) return input.map(objectKeysToLowerCase);
return Object.keys(input).reduce(function (newObj, key) {
let val = input[key];
let newVal = (typeof val === 'object') ? objectKeysToLowerCase(val) : val;
newObj[key.toLowerCase()] = newVal;
return newObj;
}, {});
};