如果我们有一个javascript对象
var calories = { apple:200, pear:280, banana:300, peach:325 }
找到含有280卡路里的(第一)水果的最佳方法是什么?
可以Object.getOwnPropertyNames(calories).forEach...
,但应该有更好的方法。
例如,我在想Array.prototype.indexOf()
对数组做同样的事情。
答案 0 :(得分:2)
小心!无法保证所有浏览器都返回相同的结果。事实上他们没有。
例如:
var x = { a: 1, b: 1 };
delete x.a;
x.a = 1;
x.indexOf(1)
应该返回什么? b
或a
?事实证明IE的属性枚举与其他浏览器不同,而且规格说完全没问题。因此,IE将返回a
,而其他浏览器将返回b
。
您可以通过调用
来验证Object.getOwnPropertyNames(x); // IE: a,b - other browsers: b,a
Object.keys(x); // same
for (var i in x) { console.log(i); } // same
显然,这里的问题是对象索引上没有“顺序”的概念,因为,那就是对象是什么:无序映射。
答案 1 :(得分:1)
但应该有更好的方法
不,真的不应该。 99%的用例都是这样的,开发人员更关心从密钥中获取价值。
答案 2 :(得分:1)
使用for..in
构造进行线性搜索:
var fruit = null;
for (var prop in calories) {
if (calories[prop] == 280) {
fruit = prop;
break;
}
}
答案 3 :(得分:0)
你可以扩展Object的原型:
// Returns one key (any) of the value if it exists, or undefined if not
Object.defineProperty(Object.prototype, "keyOf", {
value: function(value) {
for (var key in this) if (this[key] == value) return key;
return undefined;
}
});
如果您使用jQuery,则使用这种方式而不是公共Object.prototype.keyOf = ...
将使用它。
然后你可以像这样使用它:
var myArray = {...};
var index = myArray.keyOf(value);
它也适用于普通数组:[...]
,因此您也可以使用它而不是indexOf
。
请记住使用三字符运算符检查它是否未定义:
index === undefined // to check the value/index exists
index !== undefined // to check the value/index does not exist
当然,如果您愿意,可以更改函数的名称,并记住不要声明任何名为' undefined'。
的变量。还要记住,作为indexOf,它最多会返回一个定义的键,但它可能不止一个,所以在这种情况下你需要这样的东西(.keysOf(...)
):
// Returns all the keys of the value if it exists (an empty array if not)
Object.defineProperty(Object.prototype, "keysOf", {
value: function(value) {
var allKeys = [];
for (var key in this) if (this[key] == value) allKeys.push(key);
return allKeys;
}
});