Ассоциативный массив без toString и т.д.
Я хочу создать ассоциативный массив:
var aa = {} //equivalent to Object(), new Object(), etc...
и я хочу быть уверенным, что любой доступный ключ будет числом:
aa['hey'] = 4.3;
aa['btar'] = 43.1;
Я знаю, что JS не печатает, поэтому я не могу автоматически проверять это, но я могу обеспечить в своем собственном коде, что я только назначаю строки этому аа.
Теперь я беру ключи от пользователя. Я хочу показать значение для этого ключа. Однако, если пользователь дает мне что-то вроде "toString", он вернет функцию, а не int! Есть ли способ убедиться, что любая строка, которую он мне дает, - это только то, что я определяю? Это единственное решение:
delete aa['toString'];
delete aa['hasOwnProperty'];
и т.д...
Ответы
Ответ 1
Будет ли это работать для вас?
function getValue(id){
return (!isNaN(aa[id])) ? aa[id] : undefined;
}
Update:
С помощью Moss Collum и pottedmeat я рекомендую это общее решение:
function getValue(hash,key) {
return Object.prototype.hasOwnProperty.call(hash,key) ? hash[key] : undefined;
}
Update2:
Забыл ".call". (спасибо pottedmeat за указание этого)
Update3: (О ключе)
Обратите внимание на следующее: ключ будет внутренне преобразован в строку, потому что ключ на самом деле является именем атрибута.
var test = {
2:"Defined as numeric",
"2":"Defined as string"
}
alert(test[2]); //Alerts "Defined as string"
При попытке использовать объект:
var test={}, test2={};
test[test2]="message"; //Using an object as a key.
alert(test[test2]); //Alerts "message". Looks like it works...
alert(test[ test2.toString() ]);
//If it really was an object this would not have worked,
// but it also alerts "message".
Теперь, когда вы знаете, что это всегда строка, давайте ее использовать:
var test={};
var test2={
toString:function(){return "some_unique_value";}
//Note that the attribute name (toString) don't need quotes.
}
test[test2]="message";
alert(test[ "some_unique_value"] ); //Alerts "message".
Ответ 2
Одной из возможностей было бы использовать hasOwnProperty, чтобы проверить, что ключ - это то, что вы явно добавили в массив. Поэтому вместо:
function findNumber(userEnteredKey) {
return aa[userEnteredKey];
}
вы бы сказали:
function findNumber(userEnteredKey) {
if (Object.prototype.hasOwnProperty.call(aa,userEnteredKey))
return aa[userEnteredKey];
}
В качестве альтернативы вы можете использовать typeof, чтобы проверить, что что-то есть число перед его возвратом. Но мне нравится подход hasOwnProperty, потому что он заставит вас возвращать все, что вы не намеренно помещали в массив.
Ответ 3
Действительно простой ответ: когда вы создаете новый ключ, добавьте его с помощью некоторой строковой константы.
var a = {};
var k = 'MYAPP.COLLECTIONFOO.KEY.';
function setkey(userstring)
{
a[k+userstring] = 42;
}
function getkey(userstring)
{
return a[k+userstring];
}