Ассоциативный массив без toString и т. Д
-
21-08-2019 - |
Вопрос
Я хочу создать ассоциативный массив:
var aa = {} //equivalent to Object(), new Object(), etc...
и я хочу быть уверен, что любой ключ, к которому я обращаюсь, будет номером:
aa['hey'] = 4.3;
aa['btar'] = 43.1;
Я знаю, что в JS нет набора текста, поэтому я не могу автоматически проверить это, но я могу гарантировать в своем собственном коде, что я назначаю строки только этому aa.
Теперь я забираю ключи у пользователя.Я хочу отобразить значение для этого ключа.Однако, если пользователь предоставит мне что-то вроде "toString", он вернет функцию, а не int!Есть ли какой-нибудь способ убедиться, что любая строка, которую он мне дает, является только тем, что я определяю?Является ли единственное решение чем-то вроде:
delete aa['toString'];
delete aa['hasOwnProperty'];
и т.д...
Решение
Сработает ли это у вас?
function getValue(id){
return (!isNaN(aa[id])) ? aa[id] : undefined;
}
Обновить:
С помощью Коллум из Мха и мясо в горшочках Я рекомендую это общее решение:
function getValue(hash,key) {
return Object.prototype.hasOwnProperty.call(hash,key) ? hash[key] : undefined;
}
Обновление 2: Забыл ".позвонить".(спасибо pottedmeat, что указал на это)
Обновление 3: (О ключе)
Обратите внимание на следующее:Ключ будет внутренне преобразован в строку, потому что ключ на самом деле является именем атрибута.
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".
Другие советы
Одной из возможностей было бы использовать hasOwnProperty, чтобы проверить, что ключ - это то, что вы явно добавили в массив.Так что вместо:
function findNumber(userEnteredKey) {
return aa[userEnteredKey];
}
вы бы сказали:
function findNumber(userEnteredKey) {
if (Object.prototype.hasOwnProperty.call(aa,userEnteredKey))
return aa[userEnteredKey];
}
В качестве альтернативы, вы могли бы использовать typeof, чтобы проверить, является ли что-либо числом, прежде чем возвращать его.Но мне нравится подход hasOwnProperty, потому что он не позволит вам возвращать все, что вы намеренно не поместили в массив.
Действительно простой ответ:когда вы создаете новый ключ, добавляйте к нему какую-нибудь собственную строковую константу.
var a = {};
var k = 'MYAPP.COLLECTIONFOO.KEY.';
function setkey(userstring)
{
a[k+userstring] = 42;
}
function getkey(userstring)
{
return a[k+userstring];
}