Почему делает 2 == [2] в JavaScript?

Apache Конфигурация палаты общин работает отлично. Это поддерживает хранение конфигурации в широком спектре форматов на бэкенде включая свойства, XML, JNDI, и т.д. Это просто в использовании и расширяться. Для вытаскивания наибольшей гибкости из него используют фабрика , чтобы получить конфигурацию и просто использовать Интерфейс конфигурирования после этого.

Две функции Конфигурации палаты общин, которые дифференцируют его по прямому файлу Свойств, - то, что это поддерживает автоматическое преобразование в общие типы (интервал, плавание, Массивы строк), и это поддерживает замену свойства:

server.host=myHost
server.url=http://${server.host}/somePath

163
задан Michał Perłakowski 26 August 2016 в 21:11
поделиться

7 ответов

Вы можете найти алгоритм сравнения в спецификации 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"]

. Имейте в виду, что даже числовые ключи обрабатываются как имена свойств (т. Е. Строки ) до того, как произойдет какая-либо магия массива.

133
ответ дан 23 November 2019 в 21:19
поделиться

Для случая == , поэтому Doug Crockford рекомендует всегда использовать === . Он не выполняет никакого неявного преобразования типов.

Для примеров с === неявное преобразование типов выполняется до вызова оператора равенства.

8
ответ дан 23 November 2019 в 21:19
поделиться

Это из-за неявного преобразования типа оператора == .

[2] преобразуется в Number is 2 по сравнению с Number. Попробуйте унарный оператор + в [2].

> +[2]
2
10
ответ дан 23 November 2019 в 21:19
поделиться
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; 

Это просто неявное преобразование. === в этой ситуации не сработает из-за несоответствия типов.

10
ответ дан 23 November 2019 в 21:19
поделиться

Массив из одного элемента может рассматриваться как сам элемент.

Это связано с утиным вводом. Поскольку "2" == 2 == [2] и, возможно, больше.

6
ответ дан 23 November 2019 в 21:19
поделиться

Чтобы добавить немного деталей к другим ответам ... при сравнении массива с числом , Javascript преобразует массив с parseFloat (массив) . Вы можете попробовать это самостоятельно в консоли (например, Firebug или Web Inspector), чтобы увидеть, в какие различные значения Array преобразуются.

parseFloat([2]); // 2
parseFloat([2, 3]); // 2
parseFloat(['', 2]); // NaN

Для Array s, parseFloat ] выполняет операцию с первым членом массива и отбрасывает остальные.

Редактировать: Согласно подробностям Кристофа, возможно, он использует более длинную форму внутри, но результаты неизменно идентичны в parseFloat , поэтому вы всегда можете использовать parseFloat (array) как сокращение, чтобы точно знать, как он будет преобразован.

3
ответ дан 23 November 2019 в 21:19
поделиться
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!

Это интересно, дело не в том, что [0] одновременно истинно и ложно, на самом деле

[0] == true // false

Это забавный способ javascript обработка оператора if ().

7
ответ дан 23 November 2019 в 21:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: