Яка різниця між & та && у JavaScript?


82

Яка різниця між & та && у JavaScript?

Приклад-код:

var first  = 123;
var second = false;
var third  = 456;
var fourth = "abc";
var fifth  = true;
alert(first & second); // 0
alert(first & third);  // 72
alert(first & fourth); // 0
alert(first & fifth);  // 1

alert(first && second); // false
alert(first && third);  // 456
alert(first && fourth); // abc
alert(first && fifth);  // true

Здається, && - це логічне "і", яке завжди дає мені друге значення, якщо обидва істинні.

Але що таке &?

(До речі, &&, здається, "і" у Python; & схоже, є & у Python.)


Якщо вам цікаво, чому ми не використовуємо побітові операції замість логічних операторів, розгляньте 4 & 1 = 0. Використовуючи два масиви довжиною 4 і 1; побітовое: fruits.length & veggies.length === 0і логічне: fruits.length && veggies.length === true.
Том Андерсон,

Відповіді:


149

& є побітовим І

Цей оператор очікує двох чисел і перенастроює число. Якщо вони не є числами, вони призначаються числам.

Як це працює? Вікіпедія має відповідь: https://en.wikipedia.org/wiki/Bitwise_operation#AND

Примітка: У Javascript не рекомендується використовувати цей оператор , оскільки немає цілочисельного типу даних, а лише плаваюча крапка. Таким чином, плаваючі перетворюються у цілі числа перед кожною операцією, що робить її повільною. Крім того, він не має реального використання в типових веб-додатках і створює нечитабельний код.

Загальне правило: уникати. Не використовуйте його. Він рідко має місце в доступному для читання та читаному коді JS.

&& є логічним І

Він очікує двох аргументів і повертає:

  • Перший термін, який вважає помилковим
  • Останній термін в іншому випадку (якщо всі істинно-y)

Ось кілька прикладів:

0 && false          0 (both are false-y, but 0 is the first)
true && false       false (second one is false-y)
true && true        true (both are true-y)
true && 20          20 (both are true-y)

Якщо ви коли-небудь використовуєте його лише на Boolean, це саме оператор І з математичної логіки.

&& ланцюжок операторів

Причиною цього оператора, як визначено вище, є ланцюжок операторів. Ви можете створити ланцюжок для цього оператора і досі дотримуватись вищевказаних правил.

true && 20 && 0 && 100          0 (it is the first false-y)
10 && 20 && true && 100         100 (last one, since all are true-y)

&& коротке замикання

Як видно з визначення, як тільки ви виявите, що один термін неправдивий, вам не потрібно дбати про наступні терміни. Javascript навіть робить цей крок далі, умови навіть не оцінюються. Це називається коротким замиканням.

true && false && alert("I am quiet!")

Ця заява нічого не попереджає і falseповертається. Тому ви можете використовувати &&оператор як коротшу заміну оператора if. Вони еквівалентні:

if (user.isLoggedIn()) alert("Hello!")
user.isLoggedIn() && alert("Hello!")

Майже всі компресори JS використовують цей трюк, щоб заощадити 2 байти.


5
&& не повертає логічне значення в JavaScript.
Sanghyun Lee

1
AFAIK &&повертає перше значення, якщо воно хибне-y, а друге значення інакше.
duri

1
Відповідь повністю переглянутий.
Rok Kralj,

Якщо воно повертає перше значення, то я не розумію, як я можу запустити це: if ($ ('# form1'). Persley (). Validate () == true && $ ('# form2'). Parsley () .validate () == true) {// зробити щось, якщо обидві форми є дійсними}, тому що вона вийде в першій функції, якщо вона хибна, і ніколи не перевірить другу форму, як тоді запускати цей оператор IF?
user991

1
@ user777 Хіба не має значення, чи перевіряється друга форма, якщо ваша операція повинна відбуватися лише під час обох перевірок? Якщо перша форма не вдається, вся операція недійсна. Однак це насправді абсолютно окреме питання, оскільки цей потік стосується повернення , а не використання операторів if .
Ryan Williams

24

&- побітове "та". Це означає, що якщо у вас є два числа, перетворені в двійкові, результат буде числом, яке має 1цифру в тих місцях, де є обидва числа 1.

  100011  //35
& 111001  //57
---------
  100001  //35 & 57 == 33

-3

Щоб визначити, чи є два булевих значення разом істинними чи хибними, якщо ви хочете перевірити їх обидва (як перевірка на веб-сторінці), ви можете використовувати &оператор. &є побітовим І.

Якщо &&оператор виявить, що перше значення хибне, він закінчить оцінку, а не перевірить друге значення.


1
Ви не використовуєте побітове AND ( &) під час роботи з логічними значеннями. Зверніться до інших відповідей щодо відповідного використання цього оператора.
FtDRbwLXw6

@drrcknlsn, я прочитав інші відповіді, але пояснення тут працює дуже добре, чи можете ви надати більше інформації про свою претензію ??
azerafati

1
@Bludream: Пояснення у цій відповіді неправильне. Ви не використовуєте побітові оператори для логічних (булевих) порівнянь. Ви використовуєте логічні (логічні) оператори. Вони роблять різні (хоча подібні) речі, очікують різного вводу, виробляють різні результати та мають різний пріоритет оператора.
FtDRbwLXw6

1
Я б погодився, що це погана практика, але використання & з логічними значеннями буде працювати. false обчислюється як 0, а true - у 1. Я не бачу технічно неправильної відповіді з цією відповіддю, оскільки ви "можете" використовувати &, це просто не рекомендується.
dyoung

-3

З усіма високими, детальними уявленнями, вони здебільшого пропустили правду, що існує умовна оцінка, де працюватиме ТІЛЬКИ сингл &. Відповідь практичного непрофесіонала, який вирішив бити мою голову по рядку оператора IF з МНОГО РОЗРЯДІВ, прикованих && each! == до умови, спричиняв FAILURE і потребував законного використання синглу &. Я дякую Джейку Уейну (і Руссу) за їх несправедливо відхилену відповідь, яку вони правильно зрозуміли, враховуючи, що там, де є більше && that! ==, вона вже припинила свою оцінку і не продовжує подальшу роботу після того, як буде знайдена перша оцінка == !. З && він вважає, що свою роботу виконано після першої оцінки! == [напр. помилковий]. Мій невдалий код був

IF ((sessionStorage.myLable !== "LableStringA") && (sessionStorage.myLable !== "LableStringB") && (sessionStorage.myLableZ !== "LableStringA") && (sessionStorage.myLableZ !== "LableStringB")) { ...)

Тут, правильно замінивши та використовуючи одиницю & для &&, це було як практично в реальному світі, так і технічно правильною відповіддю. Ще раз дякуємо Джейку Уейну (і Руссу) за розуміння та розуміння коду.


1
Я не рекомендую використовувати щось «просто тому, що це працює», якщо ви цього не розумієте. Ви просто налаштовуєте себе на проблему пізніше, коли вона закінчується не працювати, і ви не можете її налагодити. Або ще гірше ви намагаєтеся використовувати це на співбесіді, і вони дивляться на вас як ಠ_ಠ. Якщо ваші спеціалісти не оцінюють, як ви очікуєте, у вас є логічна помилка. Немає підстав оцінювати всі 4 умовні умови, якщо перший повертає false, оскільки комбінований умовний термін ніколи не може оцінити як істинний в цьому випадку
Брендон

Дякую Брендон. Я не ставлю під сумнів ваші загальні занепокоєння. Я завжди відкладаю і запроваджую конвенцію ===. Тут, однак, ВСІ чотири оцінки були необхідними, всупереч вашому останньому надуманому коментарю. Усі чотири оцінки мали бути! == і використовувались у цьому форматі в дужках. Це було об’єднання &&, яке не могло б скластись так, як очікувалось високою логікою. Використовуючи сингл & був правильно прочитаний компіляторами у всіх основних ОС, які я тестував.
GladHeart

Як наступний крок щодо того, чому це здається і працює елегантно, це було б у ясності фальшиво зневажливої ​​відповіді Русса і Джейка. Потрібно оцінити всі чотири оцінки. Використання && зупинки / переривання, коли перша оцінка хибна. Використовуючи сингл & дозволяє продовжувати обов'язково оцінювати решту три умови. Як сказали Русс і Джейк, "Якщо оператор" && "виявить, що перше значення хибне, воно закінчить оцінку, а не перевірить друге значення." Тоді як, "якщо ви хочете перевірити їх [усіх] (наприклад, перевірку на веб-сторінці), ви можете використовувати оператор" & ". &"
Має

1
Якщо вам потрібно перевірити їх усі, ви також можете структурувати свою логіку так, if (!(sessionStorage.myLable === "LableStringA" || sessionStorage.myLable === "LableStringB") || !(sessionStorage.myLableZ === "LableStringA" || sessionStorage.myLableZ === "LableStringB")) { // fail validation}що, здається, є більш зрозумілим щодо того, що ви маєте намір (я припускаю, що ви хочете, щоб значення myLable були одним із двох значень, або не вдалося перевірити) . Якщо ваші умови не мають побічних ефектів, немає жодної причини, щоб потрібно оцінювати їх усі. Оператор працює за призначенням, але ваша логіка була перевернута
Брендон

Тай для подальшого Брендона. З повагою, він все ще упускає необхідність умов у моєму випадку, коли пошук === може бути однією з десятків можливостей кожної з чотирьох перевірок. Просто, якщо жоден з чотирьох не містить певного значення маркера сторінки, я повертаюся до запуску сценарію, щоб компенсувати його відсутність. Усі чотири ПОВИННІ всі відображатись як == !. Справа не в тому, що "якщо припустити, що ви хочете переконатись, що значення myLable є одним із двох значень", насправді myLable є одним із багатьох у косі сіна. Тому нерівноцінність - це одне питання, необхідне в 4 рази.
GladHeart
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.