Ассоциативный массив без toString и т. Д. - PullRequest
3 голосов
/ 15 декабря 2008

Я хочу создать ассоциативный массив:

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'];

и т.д ...

Ответы [ 3 ]

4 голосов
/ 15 декабря 2008

Одной из возможностей было бы использование hasOwnProperty для проверки того, что ключ - это то, что вы явно добавили в массив. Так что вместо:

function findNumber(userEnteredKey) {
    return aa[userEnteredKey];
}

вы бы сказали:

function findNumber(userEnteredKey) {
    if (Object.prototype.hasOwnProperty.call(aa,userEnteredKey))
        return aa[userEnteredKey];
}

Кроме того, вы можете использовать typeof, чтобы проверить, что что-либо является числом, прежде чем возвращать его. Но мне нравится подход hasOwnProperty, потому что он не даст вам вернуть то, что вы не умышленно поместили в массив.

3 голосов
/ 15 декабря 2008

Будет ли это работать для вас?

function getValue(id){
  return (!isNaN(aa[id])) ? aa[id] : undefined;
}

Обновление:

С помощью Moss Collum и pottedmeat Я рекомендую это общее решение:

function getValue(hash,key) {
    return Object.prototype.hasOwnProperty.call(hash,key) ? hash[key] : undefined;
}

Update2: Забыл ".call". (спасибо 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".
2 голосов
/ 15 декабря 2008

Действительно простой ответ: когда вы создаете новый ключ, добавьте к нему некоторую собственную строковую константу.

var a = {};
var k = 'MYAPP.COLLECTIONFOO.KEY.';

function setkey(userstring)
{
  a[k+userstring] = 42;
}

function getkey(userstring)
{
  return a[k+userstring];
}
...