Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript "==" operator lies

Tags:

javascript

The following confuses me greatly. As noted in the comments, the compares seem to work by themselves, but when put together they don't

The while should run for all days in the same month, then increment i by one, then start over again.

I have laced the whole sequence up with console.log to try to figure it out, but it doesn't make any sense. Everything seems to equal one another, but still fails the "==" test in the while statement.

  var i=0;
  var currentdate = 0;
  var currentmonth = 0;
  var opensmonth = 0;
  var opens = [
  { "date":"3/30/2006","zip":"30038","latitude":"33.676358","longitude":"-84.15381"},
  { "date":"4/31/2006","zip":"30519","latitude":"34.089419","longitude":"-83.94701"}
  ];
  intid = setInterval("stepthrough()", 250);
  function stepthrough() {
    //figure out first date.
    if (currentdate == 0) { // we've not been run before
      currentdate = opens[0]["date"];
      currentmonth = currentdate.split("/", 1);
      console.log("Current Month: >" + currentmonth +"<");
    }
    console.log("Current month: " + currentmonth + " And opensdate: " + opens[i]["date"].split("/", 1));

    // 
    // TWILIGHT ZONE ENTERED.
    // 
    if (currentmonth == 3 ) { 
      console.log("Current month equals 3."); // PASSES
    }
    if (opens[i]["date"].split("/", 1) == 3) {
      console.log("Opens date equals 3."); // PASSES
    }
    // BOTH THE ABOVE TESTS PASS IN CHROME AND SAFARI WHAT THE F*$K JAVASCRIPT

    while(opens[i]["date"].split("/", 1) == currentmonth) { // WHY DOESNT THIS WORK I HATE COMPUTERS
      console.log("Trying to add a point one."); 
      addpoint(i);
      i++; 
      console.log("Trying to add a point."); 
    }

    //set the date for next iteration
    currentdate = opens[i]["date"];
    currentmonth = currentdate.split("/", 1);
    console.log ("Current date is now: " + currentdate + " and current month is now: " + currentmonth);
    jQuery('div#date').text(currentdate);

    //if (i>=5000) {
    if (!opens[i]["date"]) {
      console.log("Clearing interval");
      clearInterval(intid);
      //jQuery('div#date').text("Limited at 5000 records")
    }
  }
like image 345
Jim Hodgson Avatar asked Nov 08 '11 19:11

Jim Hodgson


People also ask

What is == in JS?

The equality operator ( == ) checks whether its two operands are equal, returning a Boolean result. Unlike the strict equality operator, it attempts to convert and compare operands that are of different types.

Why does JavaScript use === instead of ==?

Use === if you want to compare couple of things in JavaScript, it's called strict equality, it means this will return true if only both type and value are the same, so there wouldn't be any unwanted type correction for you, if you using == , you basically don't care about the type and in many cases you could face ...

What is not equal in JavaScript?

What is “!= ” in JS? The JavaScript not equal or inequality operator (!=) checks whether two values are not equal and returns a boolean value.

Which operator will return false if two value are equal?

The !== operator returns false if two values are strictly equal to each other and returns true otherwise.


2 Answers

JavaScript typing is implicit. This means if it thinks you are trying to treat something as a number, it will do it's best to treat that object as a number, even if it is, say, a boolean, or a string.

When doing standard ==, JavaScript will use implicit conversions to try and match types. This often results in unexpected comparison results.

If you want to force strong comparisons, you must use the === operator.

That being said, if you are examining the 'number' representation of a string, e.g. "123", and want to use strong comparisons, you must convert it to a number using parseInt(str, 10);

For some examples on implicit typing in action, see the JavaScript truth table answer.

like image 106
Matt Avatar answered Oct 07 '22 09:10

Matt


Here's the problem: ["1"] == 1 in Javascript, because of the implicit conversions @Matt describes. But ["1"] != ["1"] in Javascript, because you're comparing two arrays, and thus two objects, and object comparisons are only true if they point to the same object, not if they point to two identical objects.

When you assign with .split('/', 1), you're getting an array like ['3'], not the string "3" (as I think you might be assuming). So:

currentmonth = currentdate.split("/", 1); // currentmonth is ["3"]
currentmonth == 3; // true, as described above
opens[i]["date"].split("/", 1) == 3; // true, because left-hand evals to ["3"]
opens[i]["date"].split("/", 1) == currentmonth; 
// false, because you're comparing two arrays - ["3"] != ["3"]

To fix this with your current code, you can just get the string, not the array, like this:

currentmonth = currentdate.split("/")[0]; // currentmonth is "3"
opens[i]["date"].split("/")[0] == currentmonth; // true, both sides are "3"
like image 4
nrabinowitz Avatar answered Oct 07 '22 10:10

nrabinowitz