Чому ",,," == масив (4) у Javascript?


119

Завантажте перекладач / консоль і спробуйте порівняння

> ",,," == Array(4)
True

Чому? Спочатку я думав, може, оскільки ви могли подумати про ",,," як масив з чотирьох символів із завершальним фрагментом "\ 0", це може бути причиною, але

> "..." == Array(4)

Повертається "Неправдиво". Так чому? Я знаю, що це якийсь ідіосинкратичний бік качки, що набирає у Javascript, але просто цікаво, що підкреслює цю поведінку. Зробив це завдяки чудовій презентації Зеда Шоу тут, до речі .


14
Мало мов, крім C, використовують нульове завершення способом, видимим програмісту.
Джої

7
Якщо я можу запитати, що призводить до цього відкриття?
SomeKittens

1
@SomeKittens Зед Шоу чітко згадує це у відео, на яке я пов’язаний у своєму запитанні (як критику Javascript). Ура!
ZenLikeЦе

5
@SomeKittens Це також згадується в (досить добре відомо) «ВАТ» говорити, показуючи деякі примхи в Рубі і JavaScript destroyallsoftware.com/talks/wat
Cronco

5
Це одна з багатьох вагомих причин завжди використовувати ===замість цього ==.
wprl

Відповіді:


178

Оскільки права операнд перетвориться в рядок і строкове представлення Array(4)є ,,,:

> Array(4).toString()
  ",,,"

Якщо ви використовуєте функцію конструктора масиву і передаєте число, воно встановлює довжину масиву до цього числа. Отже, ви можете сказати, що у вас є чотири порожні індекси (такі ж, як [,,,]), а представлення рядків за замовчуванням масивів - це розділений комою список його елементів:

> ['a','b','c'].toString()
  "a,b,c"

Як працює порівняння, описано в розділі 11.9.3 специфікації . Там ви побачите ( x == y):

8. Якщо Type ( x ) є String або Number та Type ( y ) - Object,
поверніть результат порівняння x == ToPrimitive ( y ).

(масиви - це об'єкти в JavaScript)

і якщо ви будете слідувати ToPrimitiveметоду, ви зрештою виявите, що він викликає toString.


2
Гаразд, зараз це все має сенс для мене. Дякую.
ZenLikeЦе

6
Це, в свою чергу, тому, що масиви строковуються так, ніби вони використовуються Array.join(",").
duskwuff -inactive-

Ви повинні бути кривавим пацієнтом, щоб програмувати в javascript
matcheek


31

Спробуйте використовувати ===. При використанні ==в Javascript він намагатиметься передавати змінні, призводячи до таких проблем, як ця. Консоль литтяArray(4) на представлення рядків (тобто Array(4).toString), що є ",,,". Причина коми в тому, що .toString()функція додає їх до окремих елементів у масиві.

Дивіться фрагмент нижче:

document.write( Array(4).toString() );


18

Це тому, що Array(4)ініціалізує масив із 4 порожніх значень, ==неявно перетворюється, таким чином:

 ",,," == Array(4)

 ",,," == Array(4).toString()

 ",,," == ["", "", "", ""] // note 3 commas for 4 values

 ",,," == ["", "", "", ""].toString()

Чи всі схожі.

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


5

Порівняння масиву з рядком примушує масив до рядка перед порівнянням. Примусовий порожній 4-елементний масив до рядка дає точний рядок.


4

Я спершу подумав, що це щось із "прототипом" ... але після невеликого розслідування я дійшов сумного висновку ...

Мабуть, це внутрішня і більш незрозуміла річ js з не так багато логіки ...

Просто спробуйте

Array(4)==Array(4)

і ніякого примусу до типів також ...

Array(4)===Array(4)

і ти отримаєш ЛАЖНИЙ

ви знаєте , що null==null, null===nullнавіть undefined==undefinedі undefined===undefinedповертає TRUE , ... так ... це трохи затемнити ...

Array(4)==[,,,] має бути правдою також


ZEE, масив (4) == [,,,] не буде правдою. Якщо порівнювати об’єкт з примітивним, то об’єкт буде перетворений на примітивний. Ось чому вона викликає toString ().
devsathish

масив (x) має бути адресою конструктора ... у будь-якому випадку в системі (не турбуйте, яка система) <identity_X> === <identity_X> завжди повинен бути правдивим!
ZEE
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.