Что означает && в javascript при использовании в элементах html?

При обновлении Диспетчера тегов Google для поддержки CSP и nonce говорят использовать этот скрипт:

(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;var n=d.querySelector('[nonce]');
n&&j.setAttribute('nonce',n.nonce||n.getAttribute('nonce'));f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');

n&&j.setAttribute() меня сбивает с толку; не уверен, что это просто недостаток знаний Javascript или здесь происходит что-то еще странное. n и j оба являются элементами HTML. setAttribute() добавляет атрибут nonce к элементу j и не имеет возвращаемого значения. Что означает n&&? Разве это не просто «и» элемента n и возвращаемое значение setAttribute? Но тогда это ничего не делает со значением этого и?

Или на самом деле сначала вычисляется n&&j, и этот сценарий фактически вызывает setAttribute как для n, так и для j? Если это так, то мне это кажется странным поведением.

Когда я вставляю этот код в Visual Studio, он автоматически добавляет пробелы. Я предполагал, что n && j.setAttribute() — это то же самое, что n&&j.setAttribute(), но действительно ли они разные?

Вы смотрите на минимизированный код, который предназначен для создания максимально короткой программы. Это часто приводит к использованию в языке уловок/умных сокращений, таких как сокращение оператора if/else до && и других логических операторов. Переменные Javascript не могут содержать &, поэтому n&&j анализируется как n && j.

Andy Ray 06.09.2024 22:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
1
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

В этом контексте это фактически эквивалентно:

if (n) {
    j.setAttribute(...);
}

Нет никакой разницы между n&&j.setAttribute() и n && j.setAttribute(). Пробелы не имеют значения между токенами в JavaScript. Оператор . имеет более высокий приоритет, чем &&, поэтому он всегда интерпретируется как

n && (j.setAttribute())

Так что VS Code поступил правильно, переформатировав его таким образом, чтобы сделать его более читабельным.

Чтобы получить то, что, по вашему мнению, могло быть задумано, вам нужно добавить круглые скобки:

(n && j).setAttribute()

Но это не то, что делал исходный код.

Спасибо! Я не собирался использовать (n && j).setAttribute(), но думал, что, возможно, именно это и делал код.

GendoIkari 06.09.2024 22:33

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

Barmar 06.09.2024 22:34

К сожалению, неправильно прочитали это как «то, что вы, возможно, имели в виду». Я знал о логическом коротком замыкании, но мне не приходило в голову, что 1) это можно сделать между логическим значением и функцией, которая не возвращает логическое значение; или 2) что это можно сделать само по себе, без использования оператора if или присвоения результатов чему-либо. Исходя из мира C#, ни одна из этих двух вещей не разрешена.

GendoIkari 06.09.2024 22:37

Ни одно из значений не является логическим. n является либо элементом, либо null (если querySelector() ничего не находит), а null считается ложным в логическом контексте. Затем вы добавляете тот факт, что любое выражение можно использовать в качестве утверждения. Я не знаю C#, но в C и C++ это похоже.

Barmar 06.09.2024 22:42

Это просто обычное старое Логическое И.

Это работает благодаря тому факту, что JS лениво оценивает &&.

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

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

То, что результат даже не используется, не беспокоит JS :-)

Другие вопросы по теме

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