Got confused by this behaviour. I thought doing something like:
if (variable name)
{
... do this...
}
should work. However if the variable is not defined, I just get 'ReferenceError: Can't find variable: "variable name, and the else block won't even be executed. For example the following snippet that I got off another StackOverflow question doesn't work when I test it. Any suggestions?
if(persons_name)
{
var name = persons_name;
}
else
{
var name = "John Doe";
}
if (typeof persons_name !== 'undefined') {
...
} else {
...
}
Note that you don't need braces with typeof.
Unlike a property, an unqualified name has to be defined before you can use it. So you if you were looking for a global variable persons_name you could write
if (window.persons_name)
and it would evaluate to undefined if persons_name didn't exist. Alternatively, you can simply declare persons_name if you expect it to exist.
var persons_name;
This won't change the value of persons_name if it already exists.
var name = (typeof persons_name !== 'undefined' || !(!!persons_name)) ?
persons_name :
'John Doe';
by saying var name; you define the variable; and by saying var name = "john doe"; you assign it a value.
Related
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.
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:
Checking if a variable exists in javascript
What are undeclared and undefined variables in JavaScript?
JS Interview Question: What’s the difference between a variable that is: null, undefined or undeclared?
JavaScript check if variable exists (is defined/initialized)
Strict mode
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; }
Thanks for all of the help! I've pieced together a simple solution that fits my needs from all of the answers if anyone wants it. The only drawback is that variable names must be passed as strings. It uses a try catch block but I can still use it for my original use case (assign a constant based on it).
function declared(variable) {
let declared = true;
try {
eval(variable);
} catch (e) {
if (e.name === "ReferenceError") {
declared = false;
}
}
return declared;
}
let declaredVar;
console.log(declared("declaredVar")); // true
console.log(declared("undeclaredVar")); // false
function typeOf(variable) {
return eval("typeof " + variable) === "undefined"
? declared(variable)
? "undefined"
: "undeclared"
: eval("typeof " + variable);
}
const stringVar = "string";
const undefinedVar = undefined;
console.log(typeOf("stringVar")); // string
console.log(typeOf("undefinedVar")); // undefined
console.log(typeOf("undeclaredVar")); // undeclared
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!
Is it possible to check if a string is a valid function name before calling eval?
var fnString = $('#fnInput').val()
// is there any way I can check if fnString is a valid function name
// before calling the following line:
eval(fnString + '()');
I understand the risks of using eval(), this is a private project that will not be available to the public.
Depending on your scope you can do something like this:
var fnString = $('#fnInput').val();
if(typeof window[fnString] === "function") {
window[fnString]();
}
You can use eval to get the type.
if (eval(`typeof ${fnString}`) == "function") {
eval(`${fnString}()`);
}
I have this code:
var phrase = function (variable, defaultPhrase) {
if (typeof variable === "undefined") {
return defaultPhrase;
}
else {
return variable;
}
}
It's called like this:
Ext.Msg.show({title: phrase(js_shutdown,'Shutdown'), //...
What I want to do is to use a default phrase when the variable is not defined, but when I pass an undefined variable to phrase(), JS throws an undefined variable error. How do I fix this? Any other ideas to do this?
You don't need a function. The || operator is usually used:
Ext.Msg.show({ title: js_shutdown || 'Shutdown', //...
You can see || as:
someValue || defaultValue
For strings, defaultValue is used if someValue === "".
If the variable is not defined at all, you'll need to inline the typeof x === "undefined" check, because you cannot pass the variable to a function (that's a ReferenceError).
Usually using || is enough, like others have suggested. However, if you want to have 0, false and null as acceptable values, then you indeed need to check if the type of the variable is undefined. You can use the ternary operator to make it a one-liner:
var variable;
var defaultPhrase = "Default";
var phrase = (typeof variable === "undefined" ? defaultPhrase : variable);
console.log(phrase);
// => "Default"
In javascript, you typically use the OR operator || to provide an alternative value when a variable is undefined:
return variable || defaultPhrase || ''
In case variable is undefined, it will evaluate to false then the second part of the test will be evaluated, if it is also undefined, you can still return an empty string.
It's a javascript error to reference an undefined variable with no scope in your function call. So, if the variable js_shutdown doesn't exist in scope, then this:
Ext.Msg.show({title: phrase(js_shutdown,'Shutdown'), //...
is an error.
For example, this code causes an error on the line that calls the phrase() function:
var Ext = {};
Ext.Msg = {};
Ext.Msg.show = function() {console.log("success")};
function phrase(variable, defaultPhrase) {
return(variable || defaultPhrase);
}
Ext.Msg.show({title: phrase(js_shutdown,'Shutdown')});
because the javascript engine isn't able to find js_shutdown in any scope.
But, this is OK:
var Ext = {};
Ext.Msg = {};
Ext.Msg.show = function() {console.log("success")};
function phrase(variable, defaultPhrase) {
return(variable || defaultPhrase);
}
Ext.Msg.show({title: phrase(window.js_shutdown,'Shutdown')});
You can see that this works here: http://jsfiddle.net/jfriend00/JFz6R/
Because you've told the JS engine exactly where to look for js_shutdown and when it isn't there, it just passes undefined to the phrase function (as you want).
Use the logical OR operator:
var phrase = variable || defaultPhrase;
Or inline:
Ext.Msg.show({title: (js_shutdown || 'Shutdown')), //...
I would usually code this like title: js_shutdown || 'Shutdown' in the absence of possible security issues.
Shouldn't it be:
var phrase = function (variable, defaultPhrase){
if(variable == undefined){
return defaultPhrase;
}else{
return variable;
}
}
How do I check whether a variable name is "in use"? Meaning: how do I check if a variable name has already been used in a var varname = 'something' statement?
Normally, I would just check if typeof varname == 'undefined', which seems to work fine. The issue is when there is an element on the page with id="varname". Now, when I check typeof varname == 'undefined', i get false regardless, because varname is some HTML element.
varname is not "in use", but it is not undefined either.
<body id="test1"></body>
<script>
//if <body> has an id of test1, how do i check if test1 is undeclared?
console.log(typeof test1 == 'undefined'); // the <body> element causes this to be true
console.log(typeof test2 == 'undefined'); // outputs true as expected
</script>
Additionally, can you check for the corner case: var test1 = document.getElementById('test1') has been executed?
The only possible way to achieve what you need is through the evil eval(), as it is not possible to access local variables through their name as strings. (Globals are possible using window["variableNameAsString"].)
The solution snippet presented below has the following effect:
Returns true if varName was declared and initialized (even if with null) and is readable from the current scope. Otherwise returns false.
DEMO jsFiddle here.
Source:
function removeIdOfAllElementsWithId(id) {
var element, elementsFound = [];
while ((element = document.getElementById(id)) !== null) {
element.removeAttribute('id')
elementsFound.push(element);
}
return elementsFound;
}
function assignIdToElements(elements, id) {
for (var i = 0, n = elements.length; i < n; i++) { elements[i].id = id; }
}
var isDefinedEval = '(' +
function (isDefinedEvalVarname) {
var isDefinedEvalResult;
var isDefinedEvalElementsFound = removeIdOfAllElementsWithId(isDefinedEvalVarname);
try {
isDefinedEvalResult = eval('typeof '+isDefinedEvalVarname+' !== "undefined"');
} catch (e) {
isDefinedEvalResult = false;
}
assignIdToElements(isDefinedEvalElementsFound, isDefinedEvalVarname);
return isDefinedEvalResult;
}
+ ')';
Usage:
To test if a variable with name variableName is defined:
eval(isDefinedEval + '("' + 'variableName' + '")') === true
To check if it is not defined:
eval(isDefinedEval + '("' + 'variableName' + '")') === false
In the fiddle you'll find lots of unit tests demonstrating and verifying the behavior.
Tests:
Several tests are included in the fiddle;
This snippet was tested in IE7, IE8 and IE9 plus latests Chrome and Firefox.
Explanation:
The function must be used through eval() because it needs to have access to the variables locally declared.
To access such variables, a function must be declared in the same scope. That's what eval() does there: It declares the function in the local scope and then calls it with varName as argument.
Aside that, the function basically:
- Removes the ID attribute of every element that has an ID === varName;
- Checks if the variable is undefined;
- And reassign the ID of those elements it removed the attribute.
Note: this answer was heavily edited, some coments may not be still appliable.
Not sure if this what you are looking for.
if(typeof test1 == "undefined" && document.getElementById("test1") == null) {
//There is no element with an id="test1" and a variable test1
}
In a context other than the global context in some browsers, it is impossible to reliably determine if a variable has been defined (either by being declared or otherwise initialised) or not other than using try..catch.
Therefore it's not a good strategy to need to do that.
In a global context, in non–IE browsers, you can do something like:
var global = this;
if (!global.hasOwnProperty('foo')) {
// there is no global foo
}
but IE doesn't implement hasOwnProperty on the global object. Note that DOM element names and IDs do not overwrite the value of declared global variables.
But anyway, all this is useless since you may well have:
var foo = document.getElementById('foo');
What now?
I have this code:
var phrase = function (variable, defaultPhrase) {
if (typeof variable === "undefined") {
return defaultPhrase;
}
else {
return variable;
}
}
It's called like this:
Ext.Msg.show({title: phrase(js_shutdown,'Shutdown'), //...
What I want to do is to use a default phrase when the variable is not defined, but when I pass an undefined variable to phrase(), JS throws an undefined variable error. How do I fix this? Any other ideas to do this?
You don't need a function. The || operator is usually used:
Ext.Msg.show({ title: js_shutdown || 'Shutdown', //...
You can see || as:
someValue || defaultValue
For strings, defaultValue is used if someValue === "".
If the variable is not defined at all, you'll need to inline the typeof x === "undefined" check, because you cannot pass the variable to a function (that's a ReferenceError).
Usually using || is enough, like others have suggested. However, if you want to have 0, false and null as acceptable values, then you indeed need to check if the type of the variable is undefined. You can use the ternary operator to make it a one-liner:
var variable;
var defaultPhrase = "Default";
var phrase = (typeof variable === "undefined" ? defaultPhrase : variable);
console.log(phrase);
// => "Default"
In javascript, you typically use the OR operator || to provide an alternative value when a variable is undefined:
return variable || defaultPhrase || ''
In case variable is undefined, it will evaluate to false then the second part of the test will be evaluated, if it is also undefined, you can still return an empty string.
It's a javascript error to reference an undefined variable with no scope in your function call. So, if the variable js_shutdown doesn't exist in scope, then this:
Ext.Msg.show({title: phrase(js_shutdown,'Shutdown'), //...
is an error.
For example, this code causes an error on the line that calls the phrase() function:
var Ext = {};
Ext.Msg = {};
Ext.Msg.show = function() {console.log("success")};
function phrase(variable, defaultPhrase) {
return(variable || defaultPhrase);
}
Ext.Msg.show({title: phrase(js_shutdown,'Shutdown')});
because the javascript engine isn't able to find js_shutdown in any scope.
But, this is OK:
var Ext = {};
Ext.Msg = {};
Ext.Msg.show = function() {console.log("success")};
function phrase(variable, defaultPhrase) {
return(variable || defaultPhrase);
}
Ext.Msg.show({title: phrase(window.js_shutdown,'Shutdown')});
You can see that this works here: http://jsfiddle.net/jfriend00/JFz6R/
Because you've told the JS engine exactly where to look for js_shutdown and when it isn't there, it just passes undefined to the phrase function (as you want).
Use the logical OR operator:
var phrase = variable || defaultPhrase;
Or inline:
Ext.Msg.show({title: (js_shutdown || 'Shutdown')), //...
I would usually code this like title: js_shutdown || 'Shutdown' in the absence of possible security issues.
Shouldn't it be:
var phrase = function (variable, defaultPhrase){
if(variable == undefined){
return defaultPhrase;
}else{
return variable;
}
}