JavaScript Rookie
JavaScript Rookie

Reputation: 253

Comparison between String and Numbers in JavaScript

I have some code like these:

let url = "/user_auth/devices";

const params = ["clientId = 909090", "name = peter", "active = true"];

for (let i=0; i < params.length; i++) {
        url += i > 0 ? "&" + params[i] : "?" + params[i];
    }

The output will be something like: "/user_auth/devices?clientId = 909090&name = peter&active = true";

What I don't understand is that inside the for loop, since url is a string, how does a string plus a number being greater than 0?

I've tested with it:

when url plus 0, the output is /user_auth/devices0 and turns to be false when compare with 0.

when /user_auth/devices0 plus 1 the output is /user_auth/devices01 and the result is also false when compare with 0.

Does anyone know why a string plus 0 could be greater than 0?

Upvotes: 0

Views: 92

Answers (5)

NaijaProgrammer
NaijaProgrammer

Reputation: 2957

The snippet url += i > 0 is not performing a comparison between the url (a string) and 0 (a number), rather it does a comparison between i (the loop counter) and the constant 0; and both are numbers.

In order to understand what is happening, you first have to understand two things:

  • the ternary operator ?:
  • the shortcut assignment operator +=

I will address the shortcut assignment operator first. Then I will explain the ternary operator.

The shortcut assignment operator: +=

The shortcut assignment operator lets you increment and assign a value in one step. Rather than doing something like this:

a = a + 5; // first increment a by 5, then assign the result to a

This operator lets you do something like this:

a += 5; // increment and assign the result of increment a by 5 in one step

The ternary operator: ?:

The ternary operator is a shortcut way to perform an if...else operation. It is called a ternary operator because it accepts three (3) operands. For example, the classical if...else statement is written like this:

if(condition) {
  // code to execute if condition is true
} else {
  // code to execute otherwise
}

The ternary operator lets you do the above in a more elegant and concise way:

condition ? code_to_execute_if_condition_is_true : code_to_execute_otherwise

In the above snippet, the operator is the ?:, and the operands are as follows:

  • condition
  • code_to_execute_if_condition_is_true
  • code_to_execute_otherwise

The operation can also be broken into two parts:

  • The first part is the part from the condition up until the :, and is similar to the if(condition) of a classical if...else. If that condition is true, the code between the ? and the : will be executed. It is just as if you wrote:

    if(condition) {
        // code_to_execute_if_condition_is_true
    }
    
  • The second part is the part following the :, and the code following it is executed if the condition is false. It is as if you wrote:

    else {
        // code_to_execute_otherwise
    }
    

    Important: But please note that the ternary operator is one: ?: you cannot use either part in isolation. They must always be used as specified above.

Addressing the issue at hand

Now, coming to the issue at hand, this is your code:

let url = "/user_auth/devices";

const params = ["clientId = 909090", "name = peter", "active = true"];

for (let i=0; i < params.length; i++) {
   url += i > 0 ? "&" + params[i] : "?" + params[i];
}

I will first explain the part inside the loop:

url += i > 0 ? "&" + params[i] : "?" + params[i];

This code snippet can be split into two parts:

  • url +=

    Based on what we have explained so far, this is a shortcut way of writing:

    url = url + // something (we will get to that something in a bit)

  • i > 0 ? "&" + params[i] : "?" + params[i]; This is the ternary operator at play here, and it is like writing:

    if(i > 0) {
       return "&" + params[i];
    } else {
        return "?" + params[i];
    }
    

    Earlier, we talked about url += as being equivalent to url = url + // something. That something is what is returned from the second part:

    i > 0 ? "&" + params[i] : "?" + params[i];.

    And whatever that is is tacked onto the end of the url. So that if i is greater than 0 (which is the case in all but the first iteration), the url will be

    url = url + "&" + params[i].

    However, if i is 0 (which is the case on the first iteration), the url will be

    url = url + "?" + params[i].

    Since your initial url string is: "/user_auth/devices";, substituting the different iteration values for params[i], we will have:

    • on the first iteration,

      i === 0

      params[i] equals "clidenId = 909090"

      So, we will have url = url + "?" + "clientId = 909090".

      Resulting in: "/user_auth/devices?clientId = 909090";

    • On the second iteration,

      i === 1 (and therefore greater than 0)

      params[i] equals "name = peter"

      we will have url = url + "&" + "name = peter"

      Resulting in: "/user_auth/devices?clientId = 909090&name = peter";

    • The same process is repeated on the third iteration (and any subsequent iteration if you add some other elements to the params array). But since i will be greater than 0 in all subsequent iterations, the result will be obtained via a similar process to the second iteration.

Upvotes: 1

user4466350
user4466350

Reputation:

the interpreter evaluates the code from right to left.

Thus in url += i > 0 ? "&" + params[i] : "?" + params[i];

it starts by evaluating the result of i > 0 ? "&" + params[i] : "?" + params[i], then, it concatenates the result in url +=...

as other has shown, this code can be written such as:

if (i > 0) {
    url += "&";
} else {
    url += "?";
}
url += params[i];

Upvotes: 1

mplungjan
mplungjan

Reputation: 177692

  1. Any string is > 0 but you just have a poorly written ternary that tests if the loop is iteration 0 or higher

  2. use the URLSeachParams, then no need to test the & or ?

const params = ["clientId = 909090", "name = peter", "active = true"];
const sp = new URLSearchParams()
params.forEach(parm => {
  const [name,value] = parm.split("=");
  sp.set(name.trim(),value.trim()); // trim could be avoided if you had a proper key/value object
})
console.log("/user_auth/devices?"+sp.toString())

Your unpleasant array can be processed with some simple replace too

const params = ["clientId = 909090", "name = peter", "active = true"];

const search = "?"+params.toString().replace(/\s+/g,"").replace(/,/g,"&")

console.log(search)

Upvotes: 0

Djaouad
Djaouad

Reputation: 22766

This url += i > 0 ? "&" + params[i] : "?" + params[i]; is just syntactic sugar (it is called the ternary operator, which is equivalent) to:

if (i > 0) {
    url += "&" + params[i];
} else {
    url += "?" + params[i];
}

i is not being added to url, and only i is being compared to 0. And it could also be reduced to this (by factoring out params[i]):

url += (i > 0 ? "&" : "?") + params[i];

Upvotes: 2

JuZDePeche
JuZDePeche

Reputation: 789

This is a ternary expression:

i > 0 ? "&" + params[i] : "?" + params[i];

It will return "&" + params[i] when i is higher than 0 and "?" + params[i] otherwise.

In your code, you are using the += operator which adds the value returned from your ternary expression to the url.

To summarize, you are not comparing a string and a number with 0. You are adding the result from a ternary operation to a string (your variable url).

Upvotes: 2

Related Questions