Apache Конфигурация палаты общин работает отлично. Это поддерживает хранение конфигурации в широком спектре форматов на бэкенде включая свойства, XML, JNDI, и т.д. Это просто в использовании и расширяться. Для вытаскивания наибольшей гибкости из него используют фабрика , чтобы получить конфигурацию и просто использовать Интерфейс конфигурирования после этого.
Две функции Конфигурации палаты общин, которые дифференцируют его по прямому файлу Свойств, - то, что это поддерживает автоматическое преобразование в общие типы (интервал, плавание, Массивы строк), и это поддерживает замену свойства:
server.host=myHost
server.url=http://${server.host}/somePath
Вы можете найти алгоритм сравнения в спецификации ECMA (соответствующие разделы ECMA-262, 3-е издание для вашей проблемы: 11.9.3, 9.1, 8.6.2.6).
Если вы переведете задействованные абстрактные алгоритмы обратно в JS, то, что произойдет при вычислении 2 == [2]
, будет в основном следующим:
2 === Number([2].valueOf().toString())
где valueOf ()
для массивов возвращает сам массив а строковое представление одноэлементного массива является строковым представлением одного элемента.
Это также объясняет третий пример как [[[[[[[2]]]]]]]]. toString ()
по-прежнему остается строкой 2
.
Как видите, здесь задействовано довольно много закулисной магии, поэтому я обычно использую только оператор строгого равенства ===
.
Первому и второму примеру легче следовать, поскольку имена свойств всегда являются строками, поэтому
a[[2]]
эквивалентно
a[[2].toString()]
, которое просто
a["2"]
. Имейте в виду, что даже числовые ключи обрабатываются как имена свойств (т. Е. Строки ) до того, как произойдет какая-либо магия массива.
Для случая ==
, поэтому Doug Crockford рекомендует всегда использовать ===
. Он не выполняет никакого неявного преобразования типов.
Для примеров с ===
неявное преобразование типов выполняется до вызова оператора равенства.
Это из-за неявного преобразования типа оператора ==
.
[2] преобразуется в Number is 2 по сравнению с Number. Попробуйте унарный оператор +
в [2].
> +[2]
2
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
В правой части уравнения у нас есть [2], который возвращает числовой тип со значением 2. Слева мы сначала создаем новый массив с одним объектом. из 2. Затем мы вызываем [(здесь находится массив)]. Я не уверен, является ли это строкой или числом. 2 или «2». Давайте сначала рассмотрим регистр строки. Я считаю, что ["2"] создаст новую переменную и вернет null. null! == 2. Итак, предположим, что он фактически неявно преобразуется в число. a [2] вернет 2. 2 и 2 соответствуют типу (так что === работает) и значению. Я думаю, что он неявно преобразует массив в число, потому что [значение] ожидает строку или число. Похоже, что число имеет более высокий приоритет.
Кстати, мне интересно, кто определяет этот приоритет. Потому что [2] имеет номер в качестве первого элемента, так оно преобразуется в число? Или это то, что при передаче массива в [array] он пытается сначала преобразовать массив в число, а затем в строку. Кто знает?
var a = { "abc" : 1 };
a[["abc"]] === a["abc"];
В этом примере вы создаете объект с именем a с членом с именем abc. Правая часть уравнения довольно проста; он эквивалентен a.abc. Это возвращает 1. Левая сторона сначала создает массив литералов ["abc"]. Затем вы выполняете поиск переменной в объекте, передавая только что созданный массив. Поскольку это ожидает строку, он преобразует массив в строку. Теперь это вычисляется как ["abc"], что равно 1. 1 и 1 - это один и тот же тип (поэтому === работает) и равное значение.
[[[[[[[2]]]]]]] == 2;
Это просто неявное преобразование. === в этой ситуации не сработает из-за несоответствия типов.
вы создаете объект с именем a с элементом abc. Правая часть уравнения довольно проста; он эквивалентен a.abc. Это возвращает 1. Левая сторона сначала создает буквальный массив ["abc"]. Затем вы выполняете поиск переменной в объекте, передавая только что созданный массив. Поскольку это ожидает строку, он преобразует массив в строку. Теперь это вычисляется как ["abc"], что равно 1. 1 и 1 - это один и тот же тип (поэтому === работает) и равное значение.[[[[[[[2]]]]]]] == 2;
Это просто неявное преобразование. === в этой ситуации не сработает из-за несоответствия типов.
вы создаете объект с именем a с элементом abc. Правая часть уравнения довольно проста; он эквивалентен a.abc. Это возвращает 1. Левая сторона сначала создает буквальный массив ["abc"]. Затем вы ищете переменную в объекте, передавая только что созданный массив. Поскольку это ожидает строку, он преобразует массив в строку. Теперь это вычисляется как ["abc"], что равно 1. 1 и 1 - это один и тот же тип (поэтому === работает) и равное значение.[[[[[[[2]]]]]]] == 2;
Это просто неявное преобразование. === в этой ситуации не сработает из-за несоответствия типов.
Затем вы выполняете поиск переменной в объекте, передавая только что созданный массив. Поскольку это ожидает строку, он преобразует массив в строку. Теперь это вычисляется как ["abc"], что равно 1. 1 и 1 - это один и тот же тип (поэтому === работает) и равное значение.[[[[[[[2]]]]]]] == 2;
Это просто неявное преобразование. === в этой ситуации не сработает из-за несоответствия типов.
Затем вы ищете переменную в объекте, передавая только что созданный массив. Поскольку это ожидает строку, он преобразует массив в строку. Теперь это вычисляется как ["abc"], что равно 1. 1 и 1 - это один и тот же тип (поэтому === работает) и равное значение.[[[[[[[2]]]]]]] == 2;
Это просто неявное преобразование. === в этой ситуации не сработает из-за несоответствия типов.
Массив из одного элемента может рассматриваться как сам элемент.
Это связано с утиным вводом. Поскольку "2" == 2 == [2] и, возможно, больше.
Чтобы добавить немного деталей к другим ответам ... при сравнении массива
с числом
, Javascript преобразует массив
с parseFloat (массив)
. Вы можете попробовать это самостоятельно в консоли (например, Firebug или Web Inspector), чтобы увидеть, в какие различные значения Array
преобразуются.
parseFloat([2]); // 2
parseFloat([2, 3]); // 2
parseFloat(['', 2]); // NaN
Для Array
s, parseFloat
] выполняет операцию с первым членом массива
и отбрасывает остальные.
Редактировать: Согласно подробностям Кристофа, возможно, он использует более длинную форму внутри, но результаты неизменно идентичны в parseFloat
, поэтому вы всегда можете использовать parseFloat (array)
как сокращение, чтобы точно знать, как он будет преобразован.
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
Это интересно, дело не в том, что [0] одновременно истинно и ложно, на самом деле
[0] == true // false
Это забавный способ javascript обработка оператора if ().