JSLint is not passing this as a valid code:
/* global someVar: false */ if (typeof someVar === "undefined") { var someVar = "hi!"; } What is the correct way?
/*global window */ if (window.someVar === undefined) { window.someVar = 123456; } if (!window.hasOwnProperty('someVar')) { window.someVar = 123456; } /*global window */, you could use /*jslint browser: true */.if(!window.hasOwnProperty('someVar'))undefined = 'some value' ?window is a global variable, whose existence we want to check - which of course is the problem we'd like to solve in the first place./** * @param {string} nameOfVariable */ function globalExists(nameOfVariable) { return nameOfVariable in window } It doesn't matter whether you created a global variable with var foo or window.foo — variables created with var in global context are written into window.
"foo" in window anywhereUnexpected 'in'. Compare with undefined, or use the hasOwnProperty method instead. Then, I guess, the right way is: window.hasOwnProperty("nameOfVar")window is undefined there.If you are wanting to assign a global variable only if it doesn't already exist, try:
window.someVar = window.someVar || 'hi'; or
window['someVar'] = window['someVar'] || 'hi'; someVar contains a value like 0 or '', it will assign 'hi' to it instead of using the existing value.try
variableName in window or
typeof window[variableName] != 'undefined' or
window[variableName] !== undefined or
window.hasOwnProperty(variableName) "prop" in object is absolutely legal JavaScript. Remember, JSLint is for you, not you for JSLint, and JSLint is not a JavaScript. For me if ('prop' in obj) { do_it(); } is more clear (i.e. readable and maintainable), then if (obj.prop !== undefined) { do_it(); }. I would suggest you to ignore JSLint in this case. Also see stackoverflow.com/questions/6824895/….I think this is actually a problem with JSLint. It will issue the following error:
Unexpected 'typeof'. Compare directly with 'undefined'.
I believe this is bad advice. In JavaScript, undefined is a global variable that is, usually, undefined. But some browsers allow scripts to modify it, like this: window.undefined = 'defined'. If this is the case, comparing directly with undefined can lead to unexpected results. Fortunately, current ECMA 5 compliant browsers do not allow assignments to undefined (and will throw an exception in strict mode).
I prefer typeof someVar === "undefined", as you posted, or someVar in window as Susei suggested.
As of ES6 most of other answers, including the accepted answer, are incorrect, because global variables defined by let or const, or resulting from a class declaration, do not have corresponding properties on the global object (window in a browser, or global in node.js). Several of them—mainly the ones which use typeof—can also be fooled by global variables which exist but which are set to undefined.
The only fully general way to test to see if a global variable exists—regardless of whether it has been declared using var, let or const, created via a function or class declaration, created by assignment (i.e., myVar = value at the top level of a program without any declaration for myVar) or by creating a property on the global object (i.e., window.myVar = value)—is to attempt to access it via a global eval and see if TypeError is thrown.
(This builds on an idea presented by Ferran Maylinch, but with a trick to ensure that it will work properly even when encapsulated in a function.)
function globalExists(varName) { // Calling eval by another name causes evalled code to run in a // subscope of the global scope, rather than the local scope. const globalEval = eval; try { globalEval(varName); return true; } catch (e) { return false; } } undeclared = undefined; const myConst = undefined; let myLet; var myVar; globalExists('undeclared') // => true globalExists('myConst') // => true globalExists('myLet') // => true globalExists('myVar') // => true globalExists('nonexistent') // => false globalExists('globalExists') // => true - can see itself. globalExists('varName') // => false - not fooled by own parameters. globalExists('globalEval') // => false - not fooled by local variable. Note that this makes use of eval, so all the usual caveats apply: you should not supply an untrusted value as the parameter, and if you must use an untrusted value you should check to make sure that varName is a valid JavaScript identifier. Doing so is out of scope for this question, but it can be done using a (rather complex) regular expression—just beware that the correct regexp depends on the version of ECMAScript you are using, whether the code is a script or (ES6) module, whether it is in an async function, etc. etc.
log and const. I was curious about eval and, if varName is not provided by a user, I guess it should not be a dangerous usage to evaluate a variable name? How can it be weaponized? Anyway I found this interesting part on MDN: never_use_eval! and eval can be replaced with Function(`"use strict";return ${varName}`)(); I've tested it and works just as fine!eval: that is, it is perfectly safe as long as its argument is never controlled by a hostile actor. If you only ever pass string literals that are valid variable names, for example, then it is harmless. I think never use eval is not a highlight of the MDN documentation: the Function constructor is no safer than eval, I am skeptical about the claimed speed advantage, and the globalEval trick is just as good for scope control.I see no reference to globalThis here, so I'll add my answer that uses it.
All of the below if statements will work in Node.js and any browser. They should also work perfectly in Bun and Deno, though I haven't tested those two runtimes.
The bottom two, as noted in the comment, work in TypeScript strict mode, so I'd recommend those.
if (globalThis.someVar) { console.log('global someVar exists 1'); } if (typeof globalThis.someVar !== 'undefined') { console.log('global someVar exists 2'); } if (typeof someVar !== 'undefined') { console.log('global someVar exists 3'); } if ('someVar' in globalThis && globalThis.someVar) { console.log('global someVar exists 4'); } // TypeScript ok if (globalThis.hasOwnProperty('someVar')) { console.log('global someVar exists 5'); } if ('someVar' in globalThis) { console.log('global someVar exists 6'); } bfavaretto is incorrect.
Setting the global undefined to a value will not alter tests of objects against undefined. Try this in your favorite browsers JavaScript console:
var udef; var idef = 42; alert(udef === undefined); // Alerts "true". alert(idef === undefined); // Alerts "false". window.undefined = 'defined'; alert(udef === undefined); // Alerts "true". alert(idef === undefined); // Alerts "false". This is simply due to JavaScript ignoring all and any values attempted to be set on the undefined variable.
window.undefined = 'defined'; alert(window.undefined); // Alerts "undefined". undefined can still be modified: this function is perfectly legal: function foo(undefined, x) { if (x === undefined) { alert('undefined!'); } }. It will not alert if you call, for instance, foo(3). The lesson is that 'undefined' is not always a reference to the global property.This would be a simple way to perform the check .
But this check would fail if variableName is declared and is assigned with the boolean value: false
if(window.variableName){ } variableName has any falsy value (for example emtpy string), so this might not be a sufficient solution.I think the best solution is the following:
if(window.hasOwnProperty('foo')) { console.log('Variable is not declared'); } The following solution will not work if the variables is declared but is not assigned (var foo;).
typeof foo === 'undefined' typeof when the variable is undefined, But typeof seems to work everywhere now. Interactively from node (node -e "console.log(typeof foo === 'undefined')"), in the devtools console (console.log(typeof foo === 'undefined') // true) and from a file (node test.js // true) Even in with "use strict";
varis not scoped to theifblock. It's as if you had writtenvar someVarabove theif. Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…