9

I know that to find if a variable is undeclared in javascript, I can use if (typeof variable === 'undefined'). If I declare a variable as undefined (var variable = undefined), the if statement still returns true. Is it possible, in JavaScript, to find the difference between undeclared variables and variables with a value of undefined? I know that they are similar, but doing const variable = undefined and then variable = "something else" will throw an error, so they must be different.

const variable = undefined

if (typeof variable === 'undefined') {
  console.log('"variable" is undefined')
}

if (typeof undeclaredVariable === 'undefined') {
  console.log('"undeclaredVariable" is undefined')
}

I wouldn't like to use a try catch block because I want to be able to assign another constant based on this. I would like a solution like this: const isVariableDeclared = variable === undeclared, except undeclared does not exist in javascript. I know I can use let with a try catch block but am looking for something more elegant.

Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Nathan Chu
  • 635
  • 1
  • 3
  • 19
  • 1
    It's not totally clear what you're asking. But what you call `undefinedVariable` in your example is better described as *undeclared* rather than *undefined*. You can tell these, in a sense, because any reference to them *except* for the `typeof` operator will throw a `ReferenceError`. – Robin Zigmond Oct 17 '20 at 19:17
  • it is not possible. it exists only one `undefined`. – Nina Scholz Oct 17 '20 at 19:17
  • Does this answer your question? [How to unset a JavaScript variable?](https://stackoverflow.com/questions/1596782/how-to-unset-a-javascript-variable) – Thomas Sablik Oct 17 '20 at 19:18
  • 2
    Use a 'try catch' to reference the variable. I think that's the only way to check if a variable is declared. – navigator Oct 17 '20 at 19:18
  • 3
    There isn't one, except that if you use a variable you haven't declared in anything other than an assignment expression or the typeof operator your code won't run and you will get a ReferenceError. – Jared Smith Oct 17 '20 at 19:21
  • [Using typeof vs === to check undeclared variable produces different result](https://stackoverflow.com/q/31671887) – adiga Oct 17 '20 at 19:30
  • 1
    From the example you shown, did you mean undeclared? – Tsubasa Oct 17 '20 at 19:38
  • @Ava I mean undeclared and have edited the question. – Nathan Chu Oct 17 '20 at 20:56
  • @ThomasSablik No, I am asking what is the difference instead of how to change a variable to undeclared. – Nathan Chu Oct 17 '20 at 20:57
  • @nthnchu ... regarding the last sentence within the OP's explanation ... *"... but doing const variable = undefined and then variable = "something else" will throw an error, so they must be different"* .. **one can not reassign a [constant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) in JavaScript .** – Peter Seliger Oct 17 '20 at 21:01
  • @PeterSeliger I know, I was trying to show that it wasn't the same as undeclared. – Nathan Chu Oct 17 '20 at 21:02
  • @ThomasSablik I already knew how to delete a variable. Is there something I don't understand about the other question that relates it to this one? – Nathan Chu Oct 17 '20 at 21:08
  • 2
    Use an object to define it and check if the object has the own property inside, maybe that's the only way if try catch does not satisfy you – quirimmo Oct 17 '20 at 21:10
  • I think I see what you're saying (`window.hasOwnProperty("variableName")`). That only works for variables declared with var, however. You should promote that to an answer, though. – Nathan Chu Oct 17 '20 at 21:15
  • @nthnchu Not quite. This may be a purely theoretical question; but in real code, you should _always_ know if a variable is declared or not. It should never be unknown; it should never be a surprise whether a variable is declared or not. The suggestion was to use an object instead, i.e. `const object = {};` and set properties on it, e.g. `object.var1 = "something";` Checking whether `var1` and `var2` exist looks like this: `object.hasOwnProperty("var1")` and `object.hasOwnProperty("var2")`, which yield `true` and `false`, respectively. – Sebastian Simon Oct 20 '20 at 00:52

3 Answers3

2

At least in the time of writing... No, it does not seem that you can do something like this:

var a = undeclared(var) ? 'undeclared' : 'undefined'

The reason is that you cannot pass an undeclared variable to a function; It raises an error, even in non-strict mode.

The best we can do, is this:

var barIsDeclared = true;

try { bar; }
catch (e) {
  if (e.name == "ReferenceError") {
    barIsDeclared = false;
  }
}

console.log(barIsDeclared);

Why?

Undefined: It occurs when a variable has been declared but has not been assigned with any value. Undefined is not a keyword.

Undeclared: It occurs when we try to access any variable that is not initialized or declared earlier using var or const keyword. If we use ‘typeof’ operator to get the value of an undeclared variable, we will face the runtime error with return value as “undefined”. The scope of the undeclared variables is always global.

For example:

  • Undefined:
var a;
undefined
console.log(a) // Success!
  • Undeclared:
console.log(myVariable) // ReferenceError: myVariable is not defined

When we try to log an undeclared variable, it raises an error. Trying to log an undefined variable does not. We make a try catch to check for just that.

'use strict'

Worth mentioning that adding 'use strict' in your code verifies that no undeclared variable is present, and raises an error if one is present.

function define() {
 //'use strict' verifies that no undeclared variable is present in our code     
 'use strict';     
 x = "Defined";  
}

define();

ReferenceError: x is not defined

Further reading:

benhatsor
  • 1,863
  • 6
  • 20
  • Good answer, and while it's not exactly an ideal solution it helped me come up with one that worked for my purposes. – Nathan Chu Oct 18 '20 at 17:58
1

As others already did point to, the OP might want to distinguish between declared but undefined references and undeclared reference names ...

let declaredButUnassignedAndStrictlyEqualToUndefinedValue;
const declaredAndHavingAssignedTheUndefinedValue = undefined;

// There is no way of telling the above two (un/)assignements appart.

console.log(
  '(declaredButUnassignedAndStrictlyEqualToUndefinedValue === declaredAndHavingAssignedTheUndefinedValue) ?',
  (declaredButUnassignedAndStrictlyEqualToUndefinedValue === declaredAndHavingAssignedTheUndefinedValue)
);


// the `typeof` operator is of no help
// if it comes to distinguish between
// declared but undefined references
// and undeclared reference names ...

console.log(
  'typeof notDeclaredWithinScope :', typeof notDeclaredWithinScope
);

// ... just a try catch can do that.

try {
  notDeclaredWithinScope;
} catch (err) {
  // console.log(err.message);

  console.log('`notDeclaredWithinScope` does not exist within this scope.')
}
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
  • I'm looking for another way different than try catch. Good answer though, and I'll accept it if no one has another way. – Nathan Chu Oct 17 '20 at 21:03
  • @nthnchu ... As long as one is dealing with variable names as described by the original Q there will hardly be another approach. There are other, more elegant, solutions if one was allowed to only focus on property names and context. – Peter Seliger Oct 17 '20 at 21:12
0

I understood what your saying. There is no defined way to get the exact answer but there is a way to find whether it is defined or not. It is possible only if it referenced somewhere.

Eg: // Lets think x is not defined

x.substring(1);

Output: ReferenceError: "x" is not defined

So if you use try catch block method, with the help of catch error message you can identify whether it is defined or not!