Подтвердить что ты не робот

Ключами в объектах Javascript могут быть только строки?

jshashtable:

Встроенные JavaScript встроены в функции hashtable, используя обозначение квадратных скобок для свойства, если ваши ключи строки или цифры:

Из того, что я знаю, ключи являются только строками (так как числа в любом случае принуждаются к строкам). Я просто хочу проверить и убедиться, что то, что указано выше, неверно (поскольку ключи не могут быть цифрами).

Был ли стандарт ECMA что-то об этом..

Или используется конкретная реализация браузера?

4b9b3361

Ответ 1

Встроенные JavaScript встроены в функции hashtable, используя квадратные скобки для свойств, при условии, что ваши ключи строки или числа

Это кажется неправильным - ключи объекта всегда строки могут быть строками или (поскольку ECMAScript 2015, aka ECMA-262 ed 6). Но это другая тема для доступа к свойствам квадратных скобок.

См. ECMA-262 ed 3 § 11.2.1 (См. также ECMAScript 2017 (черновик):

Доступ к свойствам осуществляется по имени, используя либо точечную нотацию:

MemberExpression. ИмяИдентификатора

Вызов вызова. ИмяИдентификатора

или обозначение скобки:

MemberExpression [Выражение]

Вызов вызова [Выражение]

Точечная нотация объясняется следующим синтаксическим преобразованием:

MemberExpression. ИмяИдентификатора

по своему поведению идентичен

MemberExpression [< идентификатор-имя-строка > ]

и аналогично

Вызов вызова. ИмяИдентификатора

по своему поведению идентичен

CallExpression [< идентификатор-имя-строка > ]

где < identifier-name-string > - строковый литерал, содержащий такая же последовательность символов после обработки Unicode escape последовательностей как имя идентификатора.

Поэтому при использовании точечной нотации бит после точки должен соответствовать критериям для идентификатора. Но при использовании квадратных скобок предоставляется выражение, которое оценивается и разрешается для строки.

Вкратце, обозначается квадратная скобка, чтобы доступ к свойствам можно получить с помощью выражения, например.

var y = {};
var x = 'foo';
y[x] = 'foo value';

В приведенном выше примере x предоставляется в квадратных скобках, поэтому он вычисляется, возвращая строку 'foo'. Так как это свойство еще не существует на y, оно добавляется. Свойству foo y присваивается значение "foo value".

В общих выражениях выражение в квадратных скобках оценивается и вызывается его метод toString(). Это значение, которое используется как имя свойства.

В методе доступа к свойствам dot идентификатор не оценивается, поэтому:

y.bar = 'bar value';

создает свойство bar со значением bar value.

Если вы хотите создать числовое свойство, то:

y[5] = 5;

будет оценивать 5, см. не строку, вызов (более или менее) Number(5).toString(), который возвращает строку 5, которая используется для имени свойства. Затем ему присваивается значение 5, которое является числом.

Изменить

Этот ответ был написан, когда ECMAScript ed3 был актуальным, однако все прошло. См. Последующие ссылки и MDN.

Ответ 2

Вы правые клавиши могут быть только строками, а числовые клавиши, такие как используемые в массивах, принудительно и сохраняются в виде строк.

var arr = [true];
arr[0] === true;
arr['0'] = false;
arr[0] === false;

Спецификация ECMAScript, стр. 42: ECMA-262 Script 3rd Edition.

Произведение PropertyName : NumericLiteral оценивается следующим образом:

  • Введите значение NumericLiteral.
  • Возврат ToString (Результат (1)).

Ответ 3

Ну, вот мой ответ - в основном потому, что меня не устраивали ссылки в других (правильных) ответах - выражения для имен свойств в [] всегда были привязаны к строкам, и это поведение хорошо определено в спецификации. Таким образом, в зависимости от интерпретации цитируемой цитаты, ее можно считать вводящей в заблуждение и/или неправильной.

Однако цитата не предполагает, что x[42] и x["42"] отличаются; он указывает на вводящее в заблуждение исключение других примитивов и деталей, что только строки и числа можно использовать как "хэш-ключи" (правда, имена свойств) при нормальном разрешении свойств и, в этом смысле, цитата, возможно, правильная.

Эти правила взяты из Стандартная спецификация ECMA-262 ECMAScript 5-е издание (декабрь 2009 г.)

Из раздела "11.2.1 Аксессоры свойств" (правила производства опущены):

Произведение MemberExpression: MemberExpression [Expression] оценивается следующим образом:

     
  •   
  • Пусть baseReference будет результатом оценки MemberExpression.  
  • Пусть baseValue будет GetValue (baseReference).  
  • Пусть свойствоNameReference является результатом вычисления выражения.  
  • Пусть свойствоNameValue будет GetValue (propertyNameReference).  
  • Вызов CheckObjectCoercible (baseValue).  
  • Пусть свойствоNameString - ToString (propertyNameValue).  
  • Если синтаксическое производство, которое оценивается, содержится в коде строгого режима, пусть строгое истинно, иначе пусть   строгое ложное.  
  • Возвращает значение типа Reference, базовое значение которого является baseValue, а ссылочное имя -   propertyNameString и строгий флаг строгого режима.  

Счастливое кодирование.

Ответ 4

Ключи всегда являются строками. Это означает, что вы не можете использовать идентификатор экземпляра объекта в качестве ключа.

В Flash ActionScript 3 (использует сильные типы времени выполнения, в отличие от AS2) есть объект Dictionary, который использует строгое сравнение равенства для ключей, так что вы можете сами использовать экземпляры объектов как ключи (а также числа, строки и т.д.).

Если вы хотите сделать то же самое в JavaScript, это будет сложно, потому что вам придется создавать свои собственные уникальные идентификаторы объектов и присоединять их к каждому объекту, который вы хотите отслеживать. Некоторые из них предложили добавить функцию прототипа к классу Object, но это добавит излишнюю нагрузку на каждый объект без необходимости. В любом случае вам нужно предоставить объекту отслеживаемый идентификатор через вызов функции, который присваивает инкрементное статическое число уникальному свойству, например "__objectid__".

Тогда было бы возможно создать словарь-подобный класс с такими методами, как "Добавить" (ключ, значение), но ему нужно было бы хранить строки, числа и объекты в трех отдельных внутренних хэшах, чтобы "3" не сталкиваются с номером 3 или объектом с идентификатором 3. Метод добавления должен автоматически назначать __objectid__ любому ключу объекта типа, у которого еще нет назначенного идентификатора. Даже после всего этого вы не сможете получить доступ к словарю с помощью скобок, если только нет крючков для присвоений свойств, о которых я не знаю в JavaScript.

Ответ 5

Вот functor Array. Это полезно при использовании парадигмы функционального программирования.

javascript:
    alert(["Using  ",window.navigator.userAgent] ); 
    FunctorRA=[]; f=function(){return f}; g=function(x){return x};
    FunctorRA[f]=43;
    FunctorRA[g(function(){})]="generic";
    FunctorRA[g(g)]="idempotent";
    alert(FunctorRA);
    for (i in FunctorRA)
        alert([ "Functor[ ", i,
                "]'s\n\n value is \n\n", FunctorRA[i]].join(""));

отображается:

Using  ,Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423
    Ubuntu/10.04 (lucid) Firefox/3.6.3

пустой alert, а затем:

Functor[ function () {
    return f;
}]'s

 value is 

43

и др.

Примечание Bene:

  • alert( FunctorRA ) показывает .toString() не перечисляет нечисловые индексы
  • FunctorRA - общий объект в массиве "одежда"
  • нет прямого синтаксического эквивалента . (даже с принуждением строки eval)
    см. Динамическое имя функции в javascript? для получения подробной информации о том, как :, двоеточие, может быть встроено в имя функции, хотя обычно это разделитель, чтобы синтаксически определять инициализатор свойства, метки, ?: (условные выражения) и т.д. Аналогичная проблема существует с ., требующей экранирования всех синтаксически значимых кодов символов JavaScript, таких как (){}\n .,.... Конструкция [] эффективно делает это для заключенного в скобки выражения в целом, предположительно, откладывая оценку строки как объекта типа String. Это похоже на то, что 43.x=2 является verboten, но нет, если 43 представляется как объект типа Number на (43).x=2 или 43["x"]=2. (доказательство: javascript:alert( [ (43).x=2, 43["x"]=2 ] ) отображает 2,2, но javascript:alert(43.x=2) генерирует ошибку).

Ответ 6

Да, клавиши могут быть цифрами. Фактически, спецификация использует те же общие функции отображения как для объектов, так и для массивов.

Ответ 7

Ну, все, что вы используете для ключа, преобразуется в строку из-за функции хеширования, которая хэширует строки до почти уникального короткого набора байтов, который может быть интерпретирован как целое число, потому что целочисленное сравнение во время линейного поиска является низким и быстрым. (Объекты JavaScript - это хэш-таблицы). Вы используете объекты и массивы для использования в качестве ключа. Ключи могут быть неограниченными по размеру. Но будьте осторожны, потому что объекты javascript неупорядочены.

Вчера и сегодня я попытался обойти проблемы, возникающие в этом домене, и я написал эти решения. Первая - это обычная реализация хэш-таблицы, http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/ И там все объяснено в терминах мирян...

другой - это обновление до первого, и это детерминированный JSON stringify, который строит объекты с алфавитно упорядоченными свойствами: http://stamat.wordpress.com/2013/07/03/javascript-object-ordered-property-stringify/

Проверьте это:)

Ответ 8

Встроенные объекты JavaScript обеспечивают хеш-функции...

Да вроде. Объекты по определению являются просто набором пар ключ-значение (тогда как ключи являются строками или символами). Однако, поскольку они используются как справочные таблицы многими людьми, большинство движков выбирают хеш-таблицу типа структуры данных для внутренней реализации объектов (в некоторых случаях). Так что да, вы можете использовать объекты в качестве хеш-таблицы (но не гарантируется, что движок действительно будет использовать хеш-таблицу под капотом).

ваши ключи строки или цифры...

Числа будут преобразованы в строку при использовании в качестве клавиш ввода, как и любое другое значение. Поэтому вы можете использовать Объекты в качестве хеш-таблицы для чисел и для строк, но не для обоих одновременно:

  { "1": true }[1] // true

Если вам нужен Hashtable для произвольных/смешанных значений, Map или Set будут лучшим выбором, особенно потому, что они гарантируют O (1) время поиска.