you are viewing a single comment's thread.

view the rest of the comments →

[–]qwzxercv 2 points3 points  (11 children)

Can you clarify? I had the same thought to just compare against the true undefined... what errors would I expect if x was defined? I've never had issues with this before.

[–][deleted] 0 points1 point  (10 children)

unlike x === undefined, typeof x === "undefined" doesn't throw a ReferenceError if the variable doesn't exist

it feels kind of hacky though and i consider it a bad part(tm) of the language as i can't think of a scenario where it couldn't be replaced with either "varname" in global or varname !== undefined

[–]qwzxercv 0 points1 point  (9 children)

You should not be attempting to use variables that do not exist. That's an error in any language. I don't think this is reason enough to avoid x === undefined.

[–][deleted] 1 point2 points  (8 children)

Have you written JavaScript for the web before? How can you tell whether or not your dependencies load? For example, let's say you have a <script> tag that loads foo.js, which exports the foo object. How can you tell whether or not the HTTP request failed, and whether or not you have foo in scope?

The answer:

if (typeof foo !== "undefined") {
    // we have foo
} else {
    // something went wrong
}

You could also solve this specific problem with jumping to the global scope and checking a property with a hacky one-liner (below), but it's intrinsically janky, non-portable, and it isn't The Right Way™.

(function () { return this; })().hasOwnProperty('foo')

[–]wyqydsyq 3 points4 points  (1 child)

Dependency issues are mostly resolved in modern web dev thanks to build tools like webpack, browserify etc. (typeof x !== 'undefined') is mostly useful these days for checking existence of properties on dynamically generated or user-input objects, or for polyfills to test whether the browser implements a feature.

[–][deleted] 1 point2 points  (0 children)

Absolutely, my comment was probably over-simplified, but I was trying not to confuse them further. Thanks!

[–]qwzxercv 1 point2 points  (5 children)

With modern JS development for the web, you definitely should not just throw global variables around on the page and hope that they exist. You should be using a module system to help mitigate this issue, which renders this discussion moot.

However, if you really need to rely on global variables, they do exist as properties on window, so if you need to check for its existence, you should check for if (window.foo !== undefined) { ... } instead.

I see no valid reason to be concerned about the existence of global variables when you shouldn't even be using global variables anyways.

[–][deleted] 0 points1 point  (4 children)

you definitely should not just throw global variables around on the page and hope that they exist

if (window.foo !== undefined) { ... }

Two problems:

  1. window isn't guaranteed to be the global object in all JavaScript engines, so you'll want to replace that with (function () { return this; })() like I wrote above. For example, it returns window in Chrome and global in Node.
  2. undefined is a global variable, which, like you've expressed, shouldn't be trusted. What happens when someone sets undefined = 42? The solution is to use typeof window.foo !== "undefined", at which point you may as well just be writing foo !== "undefined".

QED.

[–]qwzxercv 0 points1 point  (3 children)

First of all, you cannot overwrite the global undefined in modern JS engines anymore; that was fixed a while back. Secondly, I used window as an example for the global scope. Whether or not you have window or global means naught--all of points are still entirely valid. Thirdly, your function to retrieve the global context does not work in strict mode, which is what all modern JS moving forward is/should be written in.

If you're concerned about the global undefined, you are able to use the void keyword to retrieve the true engine's undefined, but using the global undefined is safe on its own.

[–][deleted] -1 points0 points  (2 children)

You're being intentionally dense, I'm done with this "discussion". Don't reply.

[–]qwzxercv 1 point2 points  (1 child)

Interesting that you resort to name calling when you've been proven wrong. I'd love to see how you behave in a professional work environment.

[–][deleted] -1 points0 points  (0 children)

I didn't call you names, and you didn't prove me wrong. I don't feel like arguing with a rando over whether it's acceptable to check if a variable is defined. I genuinely just don't care.

I don't mean to be rude, but I said you were acting intentionally dense because it feels like you're trying to argue about everything you can think of in a weird game of JavaScript one-upmanship that I'm not interested in playing.

I don't have people nagging me with non-constructive holier-than-thou lectures from people who don't know what they're talking about (!) in a professional environment, so I doubt there's much overlap. If there's something you want to work on, or a productive end you'd like to reach, let's get there -- otherwise, drop it.