void(0) clarification in Javascript? - javascript

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. )

Related

Correct javascript syntax for function

I've been looking to at some old javascript on a website I run - hands up, I know very little about javascript.
I came across the following function:
var timeout = null;
function textareaResize() {
if (typeof(timeout))
clearTimeout(timeout);
timeout = setTimeout(function () {
refreshAutoGrowFields();
}, 200);
}
The intellisense tells me that the syntax typeof(timeout) is invalid, to be more specific 'unexpected constant condition', however this means nothing to me.
I'd appreciate it if someone could explain what should actually be there (if the intellisense is correct in its assumptions).
I'm not sure where that function was found, but it's definitely confusing, because it's actually inaccurate JavaScript.
What it's trying to do is make whats called a timeout, meaning a performance of a certain action or collection of code after a period of time.
In order to do this, it's attempting to set this "timeout" function to a pre-defined variable called "timeout".
The thing is, before they are setting it to the variable "timeout", for some reason they want to make sure that timeout hasn't already been set. Perhaps by setting it twice to setTimeout, it would potentially cause multiple functions to happen within the same amount of time (but perhaps not).
Anyways, in order to do that, they were trying to check if "timeout" has been set before.
The problem is the way they are checking it typeof(timeout), is completely incorrect, for 2 reasons.
First, the term "typeof" isn't usually to be used like a function call; rather, it is a keyword, much like var or return, so it shouldn't in general be used with ()s like it's used here, instead it should be used like typeof timeout == "null", but the problem is that even such a syntax would be completely invalid, because even if it was null, it wouldn't evaluate to "null", it would evaluate to "object", just try pasting the following JavaScript into a console:
typeof null
It should say "object", even typeof undefined is "undefined", which is a string, which, when put in an if statement, would still evaluate to true relatively speaking, so the if statement checking if timeout is defined or not was done completely wrong.
Instead, that if statement should simply be changed to if(timeout), removing typeof completely.
typeof will return the type of the variable you put inside.
These are some types in JavaScript
number
string
boolean
array
object
undefined
you can use the type as
let s1 = 'somevalue'
cosole.log(typeof(s1)) // prints 'string'
you can play around with that and change the contents of s1. Now to the comparing part, if you try something like
if(typeof(s1)=='number')
dothis()
else if (typeof(s1)=='string')
dothat()
tip : both are same
typeof s1
typeof(s1)
and typeof(typeof(someVar)) is always string, that's why the == operator works
Hope it helped and didn't confuse you further.

And with an Or conditional statement in react / javascript

I am trying to disable a button depending on a couple of conditions.
<Button disabled={((myobject && myobject.name === "bob") || user.registered) ? true : false} >my button</Button>
Essentially, I want to disable the button if myobject.name is "bob" or if the user is registered (eg. user.registered is not nil). As it stands now, the button seems to get disabled if myobject.name is "bob" but it seems to ignore user.registered. What am I doing wrong?
many thanks!
You can simplify your code with optional chaining and by omitting the ternary, as it is redundant here:
<Button disabled={myobject?.name === "bob" || user.registered}>my button</Button>
Inside the button tag you could try to use just the two constraints you want to impose (I didn't understand why the myobject at the beginning though). It could be something like the following:
(myobject.name === "bob" || user.registered) ? true : false
It looks like you're probably pretty close, the code you have should work fine. I would make sure to check two things. Make sure that user.registered has a "truthy" value.
If it's a string or a number it could be evaluating to false where you don't expect it. In Javascript 0 undefined null "" (empty string) and NaN are all evaluated as false
You should also make sure that myobject is defined somewhere. You'll still get a reference error if myobject never gets declared. if myobject is any of those values that evaluate to false though and user.registered == true then your code should do what I think you're trying to accomplish. If not you might need to give a little more detail as to what you expect to happen and some sample values to look at.

Why is if (undefined) evaluating to true?

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.

Is this line from Underscore.js doing equality checking actually necessary?

I've just been looking at the _.isEqual function of Underscore.js and a section of the code goes something like this:
if (a === b) return true;
if (typeof a !== typeof b) return false;
if (a == b) return true;
I'm just wondering if there's any case where the third statement could be reached and evaluate to true?
Edit: Just to be clear, this isn't my own code I'm talking about, I'm reading the source of Underscore, in particular, this line and I was curious about why they're doing that.
I've just been browsing through the Underscore repo and came across a short discussion where someone asked the exact same thing, and it looks like it is actually unnecessary.
Following the algorithm defined by the ECMAScript Language Specification in section 11.9.6 and section 11.9.3 seems to show that no pair of values should return true in the above case.
So, in short, no, that situation is not possible.
The only situation where == and === react unexpectedly is when comparing a literal string ("123") to a constructed string (new String("123")), which would fail the first test.
However, on the second test it gets caught because the constructed string has the type object, but the literal has the type string.
Based on that, I'd say no, the third statement can never be reached, and evaluate to true.
When you use the == operator and the expressions are of different types, JavaScript will generally convert the two into the same type before comparing.
For example, this can happen with null and undefined. null == undefined is true, even though null === undefined is false. However typeof null is "object", while typeof undefined is "undefined". So, in this case you should return false on the second statement.
You can read all the details in the spec (section 11.9.3), it is very involved:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
My initial guess was that it was to work around a broken browser implementation.
However after digging into the git logs for that file it looks like the corresponding line was in the very first underscore.js checkin. (I'm not gonna hunt in the parent documentcloud core.js repo...) You can see it at line 334 of https://github.com/documentcloud/underscore/commit/02ede85b539a89a44a71ce098f09a9553a3a6890 .
So now my guess is that its just cruft that got left in, never completely tested and never cleaned out.

What is the point of void operator in JavaScript?

I've seen some people using void operator in their code. I have also seen this in href attributes: javascript:void(0) which doesn't seem any better than javascript:;
So, what is the justification of using the void operator?
Explanation of its use in links:
This is the reason that bookmarklets
often wrap the code inside void() or
an anonymous function that doesn't
return anything to stop the browser
from trying to display the result of
executing the bookmarklet. For
example:
javascript:void(window.open("dom_spy.html"))
If you directly use code that returns
something (a new window instance in
this case), the browser will end up
displaying that:
javascript:window.open("dom_spy.html");
In Firefox the above will display:
[object Window]
The undefined value was not directly accessible in JavaScript until ES1.3.
An operator void <expression> was therefore included to permit access to this value.
It is sometimes useful, particularly when working with the Web API (e.g. event handlers), to ensure that the result of an expression is consistently undefined.
When the undefined property was added to the global object in ES1.3 the utility of void became non-obvious.
Hence your question.
The JavaScript, the void operator is used to explicitly return undefined. It's a unary operator, meaning only one operand can be used with it. You can use it like shown below — standalone or with a parenthesis.
void expression;
void(expression);
Lets see some examples:
void 0; //returns undefined
void(1); //returns undefined
void 'hello'; //undefined
void {}; //undefined
void []; //undefined
void myFunction();
void(myFunction());
If you ask why do you need a special keyword just to return undefined instead of just returning undefined: the reason is that before ES5 you could actually name a global variable undefined, like so: var undefined = "hello" or var undefined = 23, and most browsers would accept it; the identifier undefined was not promised to actually be undefined¹. So, to return the actual undefined value, the void operator is/was used. It's not a very popular operator though and is seldom used.
Let's see an example of function with void:
//just a normal function
function test() {
console.log('hello');
return 2;
}
//lets call it
console.log(test()); //output is hello followed by 2
//now lets try with void
console.log(void test()); //output is hello followed by undefined
void discards the return value from the function and explicitly returns undefined.
You can read more from my tutorial post: https://josephkhan.me/the-javascript-void-operator/
¹ In ECMAScript 5 and later, the global variable undefined is guaranteed to be undefined (ECMA-262 5th Ed., § 15.1.1.3), though it is still possible to have a variable inside an inner scope be named undefined.
Consider the following:
With Void
Without Void
<input type="text" id="foo" value="one fish" />
<input type="text" id="bar" value="no fish" />
The first link will swap the values of the text fields. The second link will open a new page with the text "one fish". If you use a javascript: link, the minute an expression returns something other than null or undefined, the browser will interpret that as what the link should do. By wrapping all expressions/statments in a void() function, you ensure your entire snippet of code will run. These days, this is primarily of use in Bookmarklets, as using an onclick attribute, or setting up event handlers in separate Javascript blocks/files is the "norm".
As for javascript: vs. javascript:void(), the first statement is ambiguous. You're saying, "hey, I want to run some javascript", but then you don't provide any code. It's not necessarily clear what the browser should do here. With the second statement you're saying "hey, run some javascript", and your code eventually returns undefined, which the browser knows means "do nothing".
Since I'm here, I'll also point out that using either javascript: or javascript:void(); has fallen out of favor with most people who care about markup. The better thing to do is have your onclick handler return false, and have the link pointed towards a page/resource that makes sense for people who have javascript turned off, or are using a javascript blocker such as NoScript.

Categories