1

I just came across a piece of javascript code which used an assignment statement in the place where a logical && or logical OR expression would be used:

var geo;

function getGeoLocation() {
    try {
        if ( !! navigator.geolocation ) {
            return navigator.geolocation;
        } else {
            return undefined;        
        }
    } catch(e) {
      return undefined;
    }
}


if (geo = getGeoLocation()) {  
 // ^^^^^^^^^^^^^^^^^^^^^ this is the statement I am interested in
  console.log('conditional expression was true/truthy');
}

My question is, from the perspective of the if statement, what is being returned when
geo = getGeoLocation() is evaluated?
Particularly what is it the result of? and what is the type?
is it

  • Whatever the function getGeoLocation() returned?
    (in which the type would be truthy/falsy)
  • is it the "result" of the assignment? i.e. whether or not something non-null was assigned?
    (in which case the "result" might be boolean, true/false?)
  • or something else?
the_velour_fog
  • 2,094
  • 4
  • 17
  • 29
  • Yeah, the value returned by `geolocation()` would be used to test the `if` condition. For example `if (a = false) {console.log("abc")} undefined` but `if (a = true) {console.log("abc")} VM402:1 abc` – tewathia Aug 13 '16 at 03:08
  • The "result" of an assignment is the value that was assigned. That is to say that the assignment operator returns the value that was assigned.That's why `a = b = c = "test"` works. – nnnnnn Aug 13 '16 at 03:18
  • Just read the [documentation for the assignment operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Assignment), which says clearly "The assignment operation evaluates to the assigned value" (in other words, the RHS). –  Aug 13 '16 at 04:37

3 Answers3

1
if (geo = getGeoLocation()) {  
  // ...
}

My question is, from the perspective of the if statement, what is being returned when geo = getGeoLocation() is evaluated?

Here are the chronological steps of what will happen:

  • getGeoLocation() will execute first
  • assignment operation will happen next, where whatever getGeolocation() returns will be stored in geo

    • This will be either undefined or navigator.geolocation, if it exists.
  • geo will then be evaluated (tested for truthiness) as the condition to the if statement

The equivalent of that code is the following:

geo = getGeoLocation();
if (geo) {
  // ...
}
nem035
  • 34,790
  • 6
  • 87
  • 99
  • thanks, your statement `geo = getGeoLocation(); if (geo) { // ... }` seems to me a useful way to think about it. this is pretty much the answer I was hoping for, thanks – the_velour_fog Aug 13 '16 at 03:17
  • no problem, glad to help if I can – nem035 Aug 13 '16 at 03:18
  • 2
    I would recommend writing it this way, because it is more obvious months down the track. Imagine having some bug, glancing at the code and immediately changing it to `==` because, well, that's the more common pattern - then you've introduced another bug :p – Jaromanda X Aug 13 '16 at 03:21
  • @JaromandaX - When I learnt C, I was taught that if only one of the `==` operands is a variable to put it on the right. As in, `5 == x`, not `x == 5`, or `getGeoLocation()==geo`, not `geo==getGeoLocation()`. That way if you accidentally use `=` you find the bug immediately via a compilation error. But because C coders are cowboys I was also taught that a deliberate assignment in an if (or while, etc.) condition is perfectly acceptable and I do still do that in JS if it seems appropriate. Though in JS I generally use `===` and `!==` for comparisons, so that makes a single `=` stand out more. – nnnnnn Aug 13 '16 at 03:40
  • Actually, this is somewhere between incorrect and misleading. An assignment simply evaluates to its RHS. For instance, if `geo` is a property, it might have a getter, but that getter will never be called when evaluating the `if` condition. Then you say *geo will then be coerced to a boolean*. This is also incorrect. It would be correct to say "if `geo` is truthy", which is distinctly different from being coerced to a boolean. For example, `{ valueOf: false}` is truthy, yet when coerced to a boolean is false. –  Aug 13 '16 at 04:31
  • You're absolutely right about the "coercion to boolean" part, it's fixed now. Not sure what you're indicating with the first part though, is there anything else that you think is wrong? – nem035 Aug 13 '16 at 08:14
1

If navigator succeeds you get a geolocation object, which is truthy and if it fails you can see in the else part, the function is returning undefined which is falsy.

Yasin Yaqoobi
  • 1,888
  • 3
  • 27
  • 38
-1

It could return true or false, or perhaps 1 or 0.

Simply, any value that is not 0 or false evaluates as true, we can do things like:

if (true)
    always do this
if (false)
    never do this

Or

// loop will break when v = 0
var v = 10
while (v) {
    if (v)
        do something...
    v--;
}        
Nunchy
  • 948
  • 5
  • 11