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.
Related
Is it acceptable to add an attribute or value to a JavaScript function?
Example:
var f = 1;
function foo (param) {
f++;
}
var fooFunc = foo;
fooFunc.dummy = f;
console.log('fooFunc: ' + fooFunc);
console.log('fooFunc.dummy: ' + fooFunc.dummy);
The above example creates a function (foo), then assigns it to a new variable (fooFunc) and then adds a dummy attribute to fooFunc.
When run, this example prints the text of the function first, and then it prints the expected value (1 in this case). When printing the function, it doesn't show any indication of the dummy value:
fooFunc: function foo(param) {
f++;
}
fooFunc.dummy: 1
JsFiddle here - open the browser's JavaScript console to see the log messages: http://jsfiddle.net/nwinkler/BwvLf/
Why does this work? And where is the dummy attribute stored, and why isn't it printed when I log the function?
Lastly, even if this works, is it a good idea (or an acceptable practice) to use this? I don't want to start an open ended discussion on this, but rather see if there's documented uses of this, or people discouraging this in JavaScript coding guidelines.
Everything except primitives ( null, undefined, number, string, boolean ) in JavaScript are objects. So functions are basically objects.
Objects in JavaScript can have properties and methods, hence functions too.
all functions inherit from Function.prototype and has certain properties ( name, length ) and methods ( .call, .apply ) coming through this chain.
It is sometimes very useful to keep properties attached to the function itself, like cache information, number of invocations etc. There is nothing wrong out in using it this way.
More details : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
Let's have a look at ECMAScript documentation (Which is the standard JavaScript is based on). Here's the 3rd. version of it:
http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf
Go to chapter 15, Native ECMAScript Objects.
15.3 > Function objects.
There's a lot of interesting information there concerning your question, but the first thing worth noticing is that function is an object.
As an object, it has attributes (predefined and that you can assign yourself).
For example, try:
console.log('fooFunc.name: ' + fooFunc.name);
It should display "foo" in your case.
Since it's documented quite well, you can use it as a standard way, though it is not so well-spread and may seem a bit unusual.
Hope this helps.
It is normal object behavior, whether "acceptable" or not.
By using the function keyword you are actually calling the native predefined Function() constructor. Like any object constructor it returns an object after building it. Like any object, the returned object can have properties, including other functions as method properties.
var adder = function(a, b){return a+b};
adder.subtracter = function(a, b){return a-b};
console.log(adder(1,2)); // 3
console.log(adder.subtracter(1,2)); // -1
TIP: if you want to see the adder object and its subtracter method, switch to DOM view from Console view after running the above code in console and then search for "adder". You'll see the object there, and then you can collapse to see what it's made from, including a subtracter object.
Of course, a function object is a special native object, which makes it possible to make calls like this: adder() and actually run some code. The fact that a function object is harder to inspect for custom attached properties, combined with its native special object treats (read built-in restrictive behavior), should give you a hint that, while it's possible, attaching custom properties is not the intended nor a good use of a function object.
JSHint give the following error:
Expected an assignment or function call and instead saw an expression.
For the following line of code:
(aFunctionOrNull) ? aFunctionOrNull() : someObject.someMethod();
It highlights the final ) on someMethod so I assume the error is there. The code works and JSHint doesn't have a problem when I change it to if () {} else {} syntax. I don't mind the longer syntax but I'd like to learn why JSHint says this and if this is a bad practice.
The biggest piece of confusion may come from the terminology. Is someObject.someMethod() not a function call?
Well, in general it's considered bad practice to call a function using the ternary operator(s), without assigning the return value (which is what you seem to be doing).Also, it could be worth checking what JSHint has to say about the following code:
(aFunctionOrNull || someObject.someMethod)();
If aFunctionOrNull is undefined (or null, or falsy), the logical-or-bit will cause the expression to evaluate to someObject.someMethod, and the resulting value of that is invoked (a reference to a function object, hopefully). This gives you the opportunity to write your code more "fail-safe" without the bulk of a nested ternary:
(aFunctionOrNull || someObject.someMethod || function(){})();
The grouped expression is now bound to evaluate to a truthy value, so no errors are thrown there.
To avoid JSHint nagging about your not doing anything with the return value, either assign it to a variable (which I don't really like doing), or add a little operator to the mix:
~(aFunctionOrNull || someObject.someMethod || function(){})();//bitwise not
!(aFunctionOrNull || someObject.someMethod || function(){})();//logical not, doesn't really matter which one
On your last question: someObject.someMethod is indeed a function call. More specifically, it's a call to a function object in the someObject's context.
For those who don't know this: JS functions are objects, and the called context is either explicitly set using the bind method (defined on the Function.prototype) or ad-hoc:
var referenceToMethod = someObject.someMethod;
referenceToMethod();//<-- inside the function objects, this now points to the global object
An easy way to think of it is that JS functions just float around aimlessly in memory/space/time, until they are called via a reference, the context of that reference is then passed to the function object, to determine what object it'll interact with. This is, sadly, the global object by default, or null in strict mode.
JSHint says about expressions, or expr:
This option suppresses warnings about the use of expressions where
normally you would expect to see assignments or function calls. Most
of the time, such code is a typo. However, it is not forbidden by the
spec and that's why this warning is optional.
While JSLint says:
An expression statement is expected to be an assignment or a
function/method call or delete. All other expression statements are
considered to be errors.
AFAIK, there's no problem in doing what you're doing only that it will issue a warning because it would expect you to use an if..else statement, but you can turn this off in JSHint with:
/*jshint expr:true */
There error is because a ternary is an expression. You could use it to set a variable:
var result = a ? b : c;
Notice that the ternary evaluates to either b or c. It's an expression.
That said, the warning (I believe) comes from the notion that ternaries suffer poorer readability than an if...else block. The code above can be rewritten
var result;
if (a) {
result = b;
} else {
result = c;
}
Which is easier to read than a ternary. JSHint does as much to promote readable code as it does valid code. If you're comfortable including these expressions in your code, go ahead and disable the warnings for expressions. (It's what I would do.)
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. )
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
what is the point of void in javascript
What does “javascript:void(0)” mean?
Everywhere I see this javascript:void(0); to do nothing I think. (instead of this javascript:; can be used I think)
And that day I see javascript:void(x=document.getElementById('mytext').value);void(document.getElementById('mylabel').innerHTML=x); code in the page.
My question is very simple, why void? What void does?
MDN documentation page
This operator allows inserting expressions that produce side effects
into places where an expression that evaluates to undefined is
desired.
The void operator is often used merely to obtain the undefined
primitive value, usually using "void(0)" (which is equivalent to "void
0"). In these cases, the global variable undefined can be used instead
(assuming it has not been assigned to a non-default value).
void is an operator which returns undefined, although evaluation the following expression. The brackets are not needed.
In javascript:-urls it is used because any return value would overwrite the current document (like document.write()).
I believe this is a sort of alternative to simply terminating the click even in jQuery for example. When you attach a click handler to an anchor tag, you should always return false at the end of the handler -
$("#btn").on('click',function(){
// make toast
return false;
});
Returning false cancels any other actions that would have been executed by the event.
When you attach a javasctipt:void(0) to the onclick of an element, you are preventing that event from doing anything and leaving all the work to your JavaScript.
The void operator in JavaScript will call the internal GetValue(expr), but always return undefined, regardless of what value or expressions are.
The spec says:
11.4.2 The void Operator
The production UnaryExpression : void UnaryExpression is evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
Call GetValue(expr).
Return undefined.
GetValue must be called even though its value is not used because it may have observable side-effects.
My question is, why? What sort of observable side-effects could happen? Can we demonstrate how void might alter program flow, and discuss what would happen if we didn't run GetValue?
If you're writing a program with no side effects, then a function that always returns undefined isn't helpful because it does not return useful information back to the caller. In that case, you might as well not call the function at all if you always know what you'll be getting back.
However, if a language has "side effects", even functions that return undefined can still be programatically useful. "Side-effects" is a technical term for some effect that's not a part of the return value of a function. As a concrete example, mutating the DOM is a side effect that doesn't compute and return a useful value, but you still want the state of your DOM tree to mutate. Playing a sound is also a side effect.
As a side note, void can be useful since, grammatically, it forces an expression context, so that things like function expression values can be expressed unambiguously. e.g.
void function(){alert('hi')}()
I've seen this a few times with use cases such as:
javascript:void window.open("http://foo.com")
This can be used in bookmarklets to avoid changing the value on the address bar, but still executing the code - so you would obviously want to evaluate that function and not just ignore it.
It's also sometimes used by paranoid programmers who don't trust that undefined was not overridden somewhere. If you really need to know undefined, you can compare it to void 0 (since void is a reserved keyword, it cannot be used as a function name).