I'm new to JavaScript and have hit what seems to be an obvious issue.
const item = sessionStorage.getItem('item'); // undefined
if (item) {
return item;
}
In the Chrome debugger I can see that item is coming back as undefined. I would expect the conditional to fail. To my surprise it's evaluating to true.
I thought I'd already tested this out. Why would it be coming back as true in the conditional?
I've come across other checks such as those recommended by How to check for "undefined" in JavaScript?. But... why do I have to do anything even remotely 'complex' for a simple check like this? The above approach seems so simple and elegant I'm reluctant to lose it.
I'm also seeing this approach in an example on https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage.
You're not getting the value undefined from sessionStorage, but the string "undefined", which is truthy just like any other non-empty string.
I know you're not getting the value undefined because that is impossible. sessionStorage.getItem can only return a string or null. Also note that setItem will coerce its argument to a string, so sessionStorage.setItem('item', undefined) sets item to the string "undefined".
If you want to remove an item you should use sessionStorage.removeItem('item'); instead of setting it to undefined.
Related
After reading both :
difference between "void 0 " and "undefined" , https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/void
I still have some questions.
I've read that
window.undefined can be overwritten vwhere void operator will return the undefined value always
But the example which caught my eyes was the one in MDN :
Click here to do nothing
In order to do nothing , I always thought I should write :
href="javascript:return false;"
And this leads me to another question : (at Href context !) :
javascript:void(0); vs javascript:return false;
What is the differences ?
Also - Does
function doWork() {
return void( 0 );
}
is exactly
function doWork() {
return undefined;
}
Thanks.
This will not work properly:
href="javascript:return false;"
because you are not in a function. You are thinking of this:
onclick="return false;"
which is correct since return false; is placed in a function. The false value tells the onclick to prevent the default behavior of the element.
For the return statement to work in an href attribute, you'd need a full function.
href="javascript:(function() { return false; })();"
but that's just long and ugly, and as the comments note, JavaScript in an href is generally discouraged.
EDIT: I just learned something. Having a non undefined expression as above seems to replace the elements with the return value (at least in Firefox). I'm not entirely familiar with the full ramifications of using JavaScript in an href, because I never do it.
Yes, this:
return undefined;
returns exactly the same thing this:
return void 0;
as long as the undefined variable has not been redefined or shadowed by some other value.
But while they may return the same thing, it's not entirely accurate to say they are the same thing, because:
undefined is a global variable whose default value is the undefined primitive
void is an unary operator that will replace the return value of its operand with the undefined primitive
So they both result in the undefined primitive, but they do so in a very different way.
If you specify javascript: something as a value of href attribute, this something will be evaluated when someone activates that link.
The result of this evaluation will be checked: if its typeof evaluates to 'undefined' string, nothing will happen; if not, the page will be reloaded with the evaluation's result as its content:
Nothing to see here, move along...
No, still nothing...
Check this out!
The first two links here will do basically nothing. But the third one is quite more interesting: whatever you enter in prompt will be shown to you - even an empty string! But that's not all: if you click Cancel, you would still see a new page - with null printed (as cancelled prompt returns null, and, as you probably know, typeof null is in fact object; and null converted to String is, well 'null').
It could get more interesting:
What happens here?
And here?
Well, here we still get nothing at the first link. But second link will show you 333 in IE8. :)
And that's, I suppose, answers your second question as well: typeof void(0) will always be undefined. typeof undefined could give you dragons if someone decided it's a good idea to reassign them to window.undefined. )
... And yes, javascript: return false; is just wrong: you cannot return from non-function environment. You probably confused it with onclick: return false, but that's completely another story. )
Generally, I test whether or not a variable is set with something like this:
if (variable !== '') {
do something...
}
I know there are other methods for testing variables like typeof but I don't see any advantage - is this an appropriate way to test whether or not a variable is set? Are there problems with it that I should be aware of ?
Two reasons:
1) What if the variable is set by getting the contents of an empty input box?
if(someScenario){
var variable = $('empty-box').val(); }
Perhaps this is only done in certain cases, like when someScenario is true. Later on, you want to check if that variable was set. Your means returns false rather than true. Point is, you can come up with scenarios where you get wrong answers.
There's just no reason not to do it the accepted way.
if(typeof variable !== 'undefined')
It's no slower, has no real flaws, and is only a few characters more.
2) And most importantly, using typeof makes it totally clear what you're asking. Readability is crucial, and if another programmer read the first code, they would think you were checking that it wasn't an empty string. The method using typeof makes it perfectly clear what your conditional is looking for, and reduces the odds of mistakes later on.
If variable has been declared but might not have a value then your code:
if (variable !== '') {
tests if it is not the empty string. Is that what you want? An empty string might be a valid value. Better to test for undefined, or explicitly initialise it to a value that you can then treat as "invalid" (perhaps null, or whatever suits).
If variable has not been declared at all the above code would result in an error such that execution would stop at that point - you can't test the value of a variable that doesn't exist. So if, for example, you're trying to test a global variable that is created inside a function that may not have been called yet, or perhaps you're using several JS files and one needs to test a variable that may or may not have been created by one of the other files, then the only way to do it is with:
if (typeof variable != "undefined") {
Since you're using strict equality testing, the following will all return true:
false
undefined
null
0
The only time your check will return false is when you pass in an empty string.
Is that what you want?
Check out coffeescript's existential operator, by searching "The Existential Operator" on this page: http://coffeescript.org/
The functional problem with your approach is that is that you may inadvertently assign a blank string to variable at some point prior in your script and your logic block will now do the wrong thing.
From a stylistic standpoint your solution is less desirable because your intent to check the existence of the variable is not clear. Someone who was just reading through your code for this the first time might misunderstand what you wrote to mean "I'm expecting there to be a variable named variable set to the blank string" as opposed to "Do something if this variable does not exist."
This might be highly subjective, but my recommendation is to avoid code, that needs to check, whether a variable is set (a.o.t. has some value or type).
Consider this snipplet
var a=false;
if (some_condition) a="Blah";
if (typeof(a)=='string') ....
if (a===false) ...
this makes sure, a is always set, while keeping it easily differentiable from '', null or 0
I opened a js file that I wrote a while back and although it's working, I thought I spotted an error. (JS is not my primary language)
I had this:
if( myvar = fieldval.match(mypattern))
{
//Do Stuff
}
So I think I get it. Is this a correct statement?:
A javascript assignment operation evaluates to the value being assigned.
I tested on w3schools
<script type="text/javascript">
var str="The rain in SPAIN stays mainly in the plain";
var patt1=/ain/gi;
var test
document.write(test=str.match(patt1));
</script>
and it writes "ain,AIN,ain,ain" where I might have expected it to write "true" or not to write at all because boolean true is not a string. Is my line of thought and then ultimate conclusion correct. (I ask about my line of thought on this because I do not have a lot of formal CS training.)
It is a correct statement. The new value of myvar is tested:
if ( myvar = fieldval.match(mypattern) )
When the String.match method cannot find a match, it returns null. !!null === false, so the if-block is not evaluated. When any non-empty match is found, the condition is true, and the block is evaluated.
In this case, it is very likely that the if-statement is correct, and that the following is intended:
if ( (myvar = fieldval.match(mypattern)) !== null )
Rob W is correct, however it's extremely poor practice to put an assignment in an if statement like that. In the future, anyone coming along (including yourself) will scratch their head at that statement to determine if that's what you really meant.
I highly recommend Douglas Crockford's talk: http://www.youtube.com/watch?v=taaEzHI9xyY It'll make anyone (Js dev or not) a better developer for watching it because you'll consider the implications of your coding style and what future maintainers might assume.
match returns an array of matching values, not boolean. Use test instead.
The function string.match() returns an array of matches, or null if no matches are found. The code works because null evaluates to false in an if statement, while an array evaluates to true.
So indeed, the result of str.match is stored in myvar and then myvar is evaluated as boolean. It works as expected.
Recently I installed node.js on my Windows 7 machine.
On execution of JavaScript, I get an undefined message along with successful execution of the expression.
What's wrong here? I have not noticed any other side effects.
The JavaScript functions always return something. If you don't specify something to return in the function, 'undefined' is returned by default (you can check this out in Firebug too).
Don't worry though, this doesn't affect anything, you can ignore it.
Just write "hello world"; and hit enter... it will return "hello world" instead of undefined, thus no undefined is displayed. console.log returns undefined and also logs arguments to console so you get multiple messages.
As pointed out by others, javascript function will always return undefined if you do not specify any return value. You can just ignore it. It's not going to cause any harm.
But if it's annoying you too much then you can turn it off in repl. Repl has this property ignoreUndefined which is set to false by default. You can set it to true.
Try this:
module.exports.repl.ignoreUndefined = true;
Well, the question was made some years ago, but there is still another way to explain what is happening here.
Try next command:
console.log("Hello World") || "Bye World";
As mentioned function console.log() returns undefined normally and you can choose a better return value. Since Non-strict (abstract) comparison considers undefined equal to false the || operator allows you that choice.
Considering that it is just a debugging tool, this is unnecessary in general use, but helps to understand that console displays text sent to stdout and also evals the command and displays the returned value, or undefined if no value was received.
If you need to turn on ignoreUndefined from inside a module, you can use the following line to simulate AvinashB's answer without typing into the console by yourself:
process.stdin.emit('data', "module.exports.repl.ignoreUndefined = true;\n");
node also prints undefined because IN GENERAL, it displays the return value of each command and console.log doesn't return anything.
this is happening because console.log has (null/undefined) return type
to solve this issue.. have a function returning a string..
then log that function returned value...
that will overcome the undefined issue..
const addNotes= function(msg)
{
return msg;
}
console.log(addNotes('say hello'));
Just ignore it, no need to worry at all. I too had the same issue when I called the function without any return type. So node used to print undefined return type for the called function.
function emitEvent(eventname){
eventEmitter.emit(SIV_EVENT);
}
console.log(emitEvent());
Check undefined here, https://nodejs.org/api/util.html.
To avoid seeing undefined output from commands when using Node's repl module, set ignoreUndefined to true in repl.start.
I think i might be going mad.
I use console.log() to see the state of an object and then on the next line do a console.log() on a particular property of the same object and get different values for each.
The code i'm using is:
console.log(this.pictures.Items[pic].val);
for(var i in this.pictures.Items[pic].val) {
console.log("property: %s, value: %s", i, this.pictures.Items[pic].val[i] );
}
and firebug outputs:
Picture { isLoaded=true, isSelected=false, img_src="imgs/image1.jpg", more...}
property: isLoaded, value: false
...more properties
as you can see, 'isLoaded' is true when logging the object itself but false when logging the property.
I have tried logging the object again after just in case, and it is true again.
Does anyone know what is happening here?
Thanks
Rich
I'm not entirely sure if this is what is happening to you or not, but console.log() seems to have some issues in some browsers where doing a console.log() on a value or using an index variable that is changing or being iterated in an array does not always work properly.
My guess is that it has something to do with things getting marshalled between process boundaries and perhaps a delay in the actual evaluation of the logging expression until a time in which the actual object or index being used or referenced has changed. I've seen this issue in Chrome for sure - don't know about Firefox.
You should be able to work around this particular issue by using string math to build your final string. If only the final string is passed to console.log() where everything is fully evaluated, then this issue would not impact the output.