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);
Related
I've given some thoughts on declaring a variable called undefined and evaluating a truthy if-else expression with it. I found out that it is not possible in global scope. But in MDN I've found some interesting insight about the undefined datatype. I am directly quoting from MDN
undefined is a property of the global object; i.e., it is a variable
in global scope.
It doesn't say anything about local scope. That means i can create one in local scope. So, I move on to put this insight to test. I have created an object and assign a method to it
var person = {
method : function(){
var undefined = 2
if(undefined){
console.log("undefined works as a variable")
}
}
}
person.method()
And guess what! the if statement passes the test and the string inside the console.log() gets printed on the console.This might be a dangerous thing and of course a bad practice. Is there any way to prevent the declaration of a variable named after undefined keyword in javascript's local scope ? Thanks!
To work around accidental modification of undefined, you should not write this dangerous word in your code at all.
Since you only need read access to undefined, it is recommended to always use void 0 instead, which returns undefined.
var person = {
method: function() {
var undefined = 2
if(void 0) {
console.log("this should never be printed")
} else {
console.log("void 0 is always undefined, no matter what you do")
}
}
}
person.method()
How to work with void 0 and completely get rid of the word "undefined"?
// Turn
if(myVariable === undefined) { ... }
if(typeof myVariable === "undefined") { ... }
// into
if(myVariable === void 0) { ... }
// Turn
if((myVariable === undefined) || (myVariable === null)) { ... }
// into
if(myVariable == null) { ... }
// Turn
myObject.someKey = undefined
// into
myObject.someKey = void 0
Welcome to the wonderful world of JavaScript!
There is no way to prevent someone from doing this, but there is a way to ensure that undefined will mean undefined if you set up your functions as follows (not that you should really have to do this because it would be very bad practice for anyone to actually set up a variable named undefined). Essentially smaller scoped functions could hide a higher scoped undefined variable.
// This is just a way to get a variable called "undefined"
function wrapper(){
var undefined = 10;
console.log("wrapper says undefined is: " + undefined);
// This function declared a parameter called "undefined",
// but if the function gets called with no argument, then
// the value of this, more local, argument will truly be
// undefined. If arguments are needed, just add "undefined"
// to the end of the list.
function foo(undefined){
// Formal test to ensure that undefined is what we believe it to be:
if(typeof undefined === "undefined"){
console.log("foo says undefined is: " + undefined);
}
}
// When foo is called with no arguments passed in, the parameter
// "undefined" will take on a value of undefined within the scope
// of that function.
foo();
}
wrapper();
Now, that's a bit contrived as you're not going to set up all your functions with a "fake" argument, but you could test to see if undefined has been altered with:
function wrapper(){
var undefined = 10;
console.log(undefined);
function foo(){
if(typeof undefined === "undefined"){
// undefined has not been altered
} else {
// undefined has been altered, so reset it for this scope:
let undefined;
console.log(undefined);
}
}
foo();
}
wrapper();
In the end though, you could simply prevent this from affecting your functions by adding var undefined in your functions. Hoisting will make sure that this kicks in at the top of your function, no matter where you declare it.
I can't see any way to stop it, but yes, You can restrict it passing the yes inside If you can make the scope local using ES6.
You will find how scope if changed now and it's not the same thing.
var person = {
method : function(){
let undefined = 2
if(undefined){
console.log("undefined works as a variable")
}
}
}
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 have the function:
isset = function(obj){
alert(obj !== undefined);
}
Then when I do isset(defined_variable) where defined_variable has been declared, the alert box shows true but when I do isset(undefined_variable) where undefined_variable has not been declared, the alert box does not show at all, while I expected the alert box to show false. What am I doing wrong? I have tried using typeof but the results are the same.
That's because there's a difference between undefined and undeclared.
var foo; // foo is undefined.
// bar is undeclared.
console.log(foo === undefined); // true
try {
console.log(bar === undefined);
} catch (e) {
console.error('I had an error!'); // gets invoked.
}
foo = 'something';
console.log(foo === undefined); // false
but when I do isset(undefined_variable) where udefined_variable has
not been declared, the alert box does not show at all, while I
expected the alert box to show false
because it throws an error in your console (check your console) that this variable that you are comparing is not defined.
Uncaught ReferenceError: 'c' is not defined
i tried with isset( c ) and c was not declared first
When you dereference an undeclared variable (meaning you try to use a symbol that was never wrote before), you get a Reference error.
There are several ways to deal with this, but you can't determine what are local variables in javascript. Thus, your problem can be solved dynamically only for global variables, or a given scope object.
No functions could handle local scope dynamically.
You can prefix it with window if you are in a browser context (for more context see this SO answer about global object in javascript)
This would not modify your isset function code:
isset(window.undefined_variable)
There would be another way, which would need that isset function changes, but uses the same principle (still in browser context):
isset('undefined_variable_name_wrawppped_in_a_string')
function isset(name) {
return name in window;
}
We can't really use typeof in isset, it's sad because it would be convenient since it doesn't throw a Reference Error when the variable was never declared. We could still use a form of eval to do it, but since I don't want us to go there, I won't implement it.
But now, what if you want to check several nested properties?
function isset (memoryPath, root) {
var nodeNames = memoryPath.split('.');
var expectedDepthReached = nodeNames.length;
var depthReached = 0;
var nodeName;
var node = root;
// we are gonna read it from left to right
// using Array.prototype.pop()
// reversing it will alow us to do so
nodeNames.reverse();
do {
nodeName = nodeNames.pop();
node = node[nodeName];
if (node) {
depthReached++;
}
} while (node);
return depthReached === expectedDepthReached;
}
And an exemple:
window.myGlobals = {
path: {
to: {
a: {
variable: true
}
}
}
};
isset('myGlobals.path.to.a.variable', window), // true
isset('myGlobals.path.foo', window) // false
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);
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;
}
}