Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does && in javascript mean when used on html elements?

When updating Google Tag Manager to support CSP and nonce, they say to use this script:

(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');

The n&&j.setAttribute() is confusing to me; not sure if it's just a lack of Javascript knowledge or something else weird going on here. n and j are both Html Elements. setAttribute() adds the nonce attribute to element j and has no return value. What does the n&& do or mean? Doesn't this just take the "and" of element n and the return value of setAttribute? But then it doesn't do anything with the value of that and?

Or, is it that n&&j is actually evaluated first, and this script actually calls setAttribute on both n and j? That seems like a weird behavior to me if it does.

When I paste this code into Visual Studio, it automatically adds some whitespace. I was assuming that n && j.setAttribute() is the same as n&&j.setAttribute() but are they actually different?

like image 394
GendoIkari Avatar asked Sep 14 '25 06:09

GendoIkari


2 Answers

It's taking advantage of short-circuiting of the boolean operators to implement a conditional in the shortest syntax. This is the result of a code minifier -- they replace all the variable names with short, meaningless names and use as compact syntax as possible (including omitting any unnecessary whitespace); the code isn't intended to be easily understood.

In this context it's effectively equivalent to:

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

There's no difference between n&&j.setAttribute() and n && j.setAttribute(). Whitespace has no significance between tokens in JavaScript. The . operator has higher precedance than &&, so it's always interpreted as

n && (j.setAttribute())

So VS Code was correct to reformat it that way, to make it more readable.

To get what I think you thought may have been intended, you need to add parentheses:

(n && j).setAttribute()

But that's not what the original code was doing.

like image 78
Barmar Avatar answered Sep 15 '25 21:09

Barmar


It's just the regular old Logical AND.

This works by using the fact that JS evaluates the && lazily.

So if the left side is falsy, the right side won't get evaluated at all (i.e.: a method there won't be called) since the result of the binary logic operation is already clear: false.

But if the left side is truthy, logic dictates that the right side also needs to be evaluated to get to the correct result.

That the result isn't even used doesn't bother JS :-)

like image 31
Xan-Kun Clark-Davis Avatar answered Sep 15 '25 19:09

Xan-Kun Clark-Davis