I need to be able to check if a variable exists (if if it doesn't assign it to {}) without throwing an error in javascript. When I try this code
if (a) {}
it throws uncaughtReferenceError
What I really want to do is something like this without throwing an error:
a = a || {}
or maybe it looks like this
if (a) { a = {} }
if (typeof a === 'undefined'){
// variable is not available and you can write a = {}
}
but a = a || {} is shortly
If a is a global, you can use the global object to avoid the error. In browsers, that object is window:
window.a = window.a || {};
Or, as Ozerich suggested, you can use typeof, which won't throw reference errors:
if (typeof a === 'undefined') {
a = {};
}
a = a || {}
simply won't work, because a is not defined. But you can use typeof to check if it exists or not.
a = (typeof(a) === 'undefined' ? {} : a);
Related
I happened upon something strange (at least to me), and maybe someone can elaborate on this for me:
const a = undefined;
const c = {};
/** this works correctly **/
console.log(a === undefined);
/** this does not throw an exception **/
console.log(c.someProperty === undefined);
/** this throws an exception, why? **/
console.log(b === undefined);
Just is in the example above, why is it, that if I want to check for an objects property, with === undefined which was not defined everything is okay, but as soon as I try to check for a top-level variable for being defined, I am getting an error?
Here's a fiddle.
The ECMAScript Language Specification states that accessing a nonexistent variable throws a ReferenceError (see GetValue) while accessing a nonexistent property results in undefined (see OrdinaryGet).
To check if a global variable is defined, you can use typeof, which does not throw.
console.log(typeof b === 'undefined');
Top-level variables declared with var also exist on the window object, so you can use a property access too.
console.log(window.b === undefined);
The thing is that b is not undefined, it is not even declared.You cannot call a variable that is not declared, be you can with one that is declared but undefined.
const a = undefined;
const b
const c = {};
console.log(a === undefined) //true
console.log(b === undefined) //true
console.log(c.someProperty === undefined) //true
console.log(typeof d === 'undefined') //true, it does not exist
try{
console.log(d)
} catch (e) {
console.log('error!')
} //error!
I know if you want to check if a variable a is defined you can do this
if (typeof a !== 'undefined') {
// the variable is defined
}
but what if you want to make a function out of it, like this
function checkDefined(name) {
return typeof name !== 'undefined';
}
checkDefined("a");
this wouldn't work, but how can I get it to work if I have to pass a string version of the variable name?
Thanks
Checking in global scope(window):
var a = 'test';
var b = function() {};
function checkDefined(name) {
return typeof this[name] !== 'undefined';
}
console.log(checkDefined("a"));
console.log(checkDefined("b"));
console.log(checkDefined("c"));
If you want check if variable or function is declared in class object you should pass new context to checkDefined method:
function MyCustomClass() {
this.c = 'test';
}
function checkDefined(name) {
return typeof this[name] !== 'undefined';
}
// Create new object of type MyCustomClass
var myCustomClassObject = new MyCustomClass();
// In this way you can check if variable/function is defined in object
console.log(checkDefined.apply(myCustomClassObject, ["a"]));
console.log(checkDefined.apply(myCustomClassObject, ["b"]));
console.log(checkDefined.apply(myCustomClassObject, ["c"]));
apply will call a function immediately letting you specify both the value of this and any arguments the function will receive
Inspired by this answer. I think you can try to return with eval:
function checkDefined(name) {
return eval("typeof " + name) !== 'undefined';
}
Example:
var a = 1;
checkDefined("a") // true
checkDefined(a) // true
checkDefined("b") // false
Local variables are properties of the currently scoped this object.
const log = output => document.querySelector('pre')
.innerText += output + '\n'
/* In this example, running in the browser, `this` points to `window`, but
in other environments would still point to whatever is the global object.
Bind `this` to the ``checkDefined` so to ensure it keeps the same value
as where you are calling from. */
const checkDefined = function chkDef(v) {
return typeof this[v] !== 'undefined'
}.bind(this)
a = 5
log(checkDefined('a'))
log(checkDefined('b'))
/* This is the same basic idea, but we make it a little more portable by
not binding until right before we use it, so `this` has the correct
scope. */
unboundCheckDefined = function chkDef(v) {
return typeof this[v] !== 'undefined'
}
newScope()
function newScope() {
c = 5
const checkDefined =
unboundCheckDefined.bind(this)
log(checkDefined('a'))
log(checkDefined('b'))
log(checkDefined('c'))
}
<pre></pre>
You should also pass on which object context you need to check if the variable is defined or not. If it's global pass the window object
function checkDefined(name, ref) {
if(!ref) {
ref = window;
}
return !!ref[name]
}
checkDefined("a"); //false if already not defined
var obj = { a: 1, b:2};
checkDefined("a",obj);//true
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;
}
}
I am writing a script that deals with a variable gameRegion like so:
//In the main of the script
var variable= new work();
variable.onCrash(crashHandler,{xPos:650,yPos:300});
// In function work()
var gameRegion;
var onCrashCallback;
this.onCrash = function(crashCallback,fieldSize) {
gameRegion = fieldSize;
onCrashCallback = crashCallback;
};
crashHandler(){
//unimportant
}
this.atBottom = function(ypos) {
if(ypos>gameRegion.yPos) //line with the problem
return true;
return false;
};
I am getting the console error: TypeError: 'undefined' is not an object (evaluating 'gameRegion.yPos'). Presumably that means I am not properly defining gameRegion or its variable yPos. I've been looking at this code for a while now and I can't seem to find what the problem is.
Hopefully you'll see something that I don't, but if I'm not including necessary code for context, please tell me. Thanks for any help in advance.
You have to handle 'undefined'. Which can be done in these ways:
typeof(foo) == 'undefined'
typeof foo !== 'undefined'
window.foo !== undefined
'foo' in window
The first three should be equivalent (as long as foo isn't shadowed by a local variable), whereas the last one will return true if the global varible is defined, but not initialized (or explicitly set to undefined).
You can use typeof like so -
return (typeof (gameRegion) !== "undefined" &&
typeof(gameRegion.yPos) !== "undefined" &&
ypos > gameRegion.yPos);
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;
}
}