2

Sometimes I see that it is common to do this on javascript in order to check if a variable is not undefined because it has a value assigned:

if(variable) {
  /* not undefined, do something */
}

However, I was asking to myself how can I check if variable is not undefined in the following situation:

Live Demo: http://jsfiddle.net/Vp8tN/1/

$(function() {

    var person = create('John');
    var isMarried = person.isMarried;

    console.log('isMarried: ' + isMarried);

    if(isMarried) {
        console.log('Do something!');
    }

});

function create(name) {
    var person = {};
    person.name = name;
    person.isMarried = getRandom();
    return person;
};

function getRandom() {
    var arr = [true, 'No', undefined];
    var rand = arr[Math.floor(Math.random() * arr.length)];
    return rand;
};

In this case isMarried variable can be true, 'No', or undefined.

So, my questions are...

1) How can I check if isMarried variable is NOT undefined because it is === true (equals true) or because it has a value assigned? (this last one happens when isMarried === 'No').

2) Is it possible to check this without using an extra if statement or condition?

3) What's the better approach for checking this?


In both cases described above (at number 1) I got inside the if statement. Check the output from browser console:

isMarried: true
Do something!
isMarried: undefined
isMarried: No
Do something!

PS. I am using jQuery just for testing, this question is NOT related to that framework! Thanks.

Oscar Jara
  • 13,479
  • 10
  • 58
  • 90

2 Answers2

3

You have three options for a single equality test:

  1. Strict Equality. if (person.isMarried === true) or if (person.isMarried !== undefined). Check if a variable is explicitly equal to something (with no type conversions allowed).

  2. Loose equality. if (person.isMarried == true) with type conversions allowed.

  3. Any truthy/falsey value. if (person.isMarried). This will be satified if person.isMarried contains ANY truthy value. Even "no" would be a truthy value.

If you're trying to tell the difference between "no", false and undefined, you will likely have to use more than one comparison as those are all separate values of separate types.


If you only want to know if the variable has any value (e.g. is not undefined), then you can use the strict equality check and compare to the actual undefined value:

if (person.isMarried !== undefined) {
    // there is some value in person.isMarried though it could be anything
    // other than the undefined value
}
RobG
  • 124,520
  • 28
  • 153
  • 188
jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • Note that you should really use `typeof isMarried !== 'undefined'` for the reasons outlined here: http://stackoverflow.com/a/3390426/1313439. `Direct comparisons against undefined are troublesome as undefined can be overwritten.`. Otherwise nice post. – Daniel Apr 25 '14 at 22:06
  • @Daniel - As of ES5, `undefined` is now read-only and cannot be overwritten. If you want to write more verbose code to protect against a very bad programmer in your project overwriting the value of `undefined` go right ahead. I don't allow that type of code in my projects so I don't have to worry about it. Perhaps if you are a library developer that countless bad developers are going to use, you might need to protect against this, but not if you're just writing your own code and using well known libraries. – jfriend00 Apr 25 '14 at 22:11
  • 1
    @Daniel - FYI, here's a [counter opinion](http://stackoverflow.com/questions/8783510/javascript-how-dangerous-is-it-really-to-assume-undefined-is-not-overwritten) to your link – jfriend00 Apr 25 '14 at 22:11
  • Thanks for the link, it is an interesting read. I like the analogy to C and preprocessor defines. I also was not aware of the fact that `undefined` is finally read-only. In light of that I would agree that you should no longer use the `typeof` method of checking if a variable is undefined. `!== undefined` is shorter and to the point. – Daniel Apr 25 '14 at 22:15
  • Please note browser compatibility for ECMA Script 5: http://kangax.github.io/es5-compat-table/. If you still have fears that devs may overwrite this and you have a decently large client base with older browsers, you may need to either crack the whip or continue with the `typeof` approach. – ps2goat Apr 25 '14 at 22:26
  • @ps2goat - honestly, what situation (only in IE8 and earlier) is there where somebody contributing code into your project is going to overwrite the definition of `undefined`? If I was a library author and wanted to support old versions of browsers, I'd probably protect my code, but for code you're writing for your own web pages, why should you have to worry? If I found a third party library I wanted to use doing this, I'd chuck that library immediately because it's such a bad practice that it would be indicative of poor code, plus it wouldn't work in modern browsers anyway. – jfriend00 Apr 25 '14 at 23:30
  • @jfriend00, that's why I said "If you still have fears that devs may overwrite this..." I didn't say I had those fears. It is up to the person fearing this to determine, not you or myself. – ps2goat May 02 '14 at 20:23
  • @ps2goat - the point of this discussion is to give the OP a sense of what they do and don't have to worry about - not to leave it all to them to figure out from scratch. It's my opinion that this is not something to worry about for ordinary code in your application. Your comment was informational, but implied the OP might want to actually worry about it so I asked for examples of situations for when the OP should worry about it. – jfriend00 May 02 '14 at 21:26
  • @jfriend00, you mentioned that it was not overwritable in ECMA Script 5, and I was merely informing the OP that ES5 is not compatible with all browsers. So it may be an issue for them. If they are targeting a browser that doesn't support that, then that is an acceptible situation for when it should be worried about. If they are targeting all ES5-compliant browsers, then don't worry about it. You can't just tell people that "ES5 doesn't allow it, don't worry about it," and not tell them that not all browsers support ES5. – ps2goat May 02 '14 at 21:32
  • @ps2goat - I propose that EVEN in non-ES5 browsers, you don't have to worry about it for normal application code and you haven't come up with one real-world situation where you would have to worry about it. If you're letting code in your project that redefines `undefined` (e.g. really bad code), then you have worse issues to worry about. That's my opinion and my advice to the OP. If you were writing a framework that was going to interoperate with random JS from the outside world and maybe even some hostile JS, then maybe you'd worry about it, but most people writing JS are not doing that. – jfriend00 May 02 '14 at 21:34
  • @jfriend00, while that may be true, if we just believed that OpenSSL was impenetrable, no one would have found the Heartbleed vulnerability, would they? If you're told not to worry about something and you don't have the desire to investigate, things can get messy. You should not impose an absolute on someone when what they really need/want to do is learn. No one deletes historical events from wikipedia just because they aren't relevant anymore. – ps2goat May 02 '14 at 21:37
  • @ps2goat - OK, you're perfectly welcome to use the more cumbersome method for as long as you like. I see no reason to do that for general application code and that is my opinion that I share with others. I'm not imposing anything on anyone. I'm sharing my idea for how I'd solve the original problem the OP asked about. Feel free to post your own answer if you think this is the wrong answer. FYI, if `undefined` can be overwritten so can lots of host methods that are required for normal operation. If rogue JS is in your project, you have much bigger problems than this. – jfriend00 May 02 '14 at 21:42
2
  1. isMarried !== undefined
  2. Yes, see #1.
  3. 1

See this post. https://stackoverflow.com/a/3390426/1313439

EDIT: For reasons that jfriend00 pointed out in the comments to his answer, isMarried !== undefined is probably preferable to typeof isMarried !== 'undefined'.

Community
  • 1
  • 1
Daniel
  • 1,793
  • 4
  • 14
  • 33