Are there examples of short-circuit control flow in Javascript? - javascript

http://en.wikipedia.org/wiki/Short-circuit_evaluation says "Short-circuit operators are, in effect, control structures" and http://en.wikipedia.org/wiki/Perl_language_structure#Control_structures says "Short-circuit logical operators are commonly used to affect control flow at the expression level", with a pseudo code example directly from the latter being:
expr && expr
I've seen the above sort of thing recommended in the book Minimal Perl. So why not in Javascript? Yesterday I wrote something such as the following:
myModule && myModule.myMethod(); //instead of if (myModule) myModule.myMethod();
Does anybody know of any other examples of usage of this idiom in Javascript, perhaps from open source frameworks? What might be it's disadvantages, if any (besides, "somebody might not understand it")?

myModule && myModule.myMethod() works in JavaScript. But since ECMAScript 2020, there is something better: Optional Chaining (?.):
myModule?.myMethod()

In React conditional rendering can be achieved inline with the logical && operator, see https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator Here's the pertinent snippet (my inline observations are not meant critically, checking length is the smallest and most understandable for a sample):
return (
// Don't directly check length, instead
// consider a more flexible "shouldRender" method
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);

Related

Angular Templates - inline expressions vs calling to function

Is there any difference between those two:
<li [ngClass]="{disabledField: condition1 && condition2 && condition3}">Click</li>
vs
<li [ngClass]="{disabledField: shouldDisableField()}">Click</li>
and in component class:
shouldDisableField(): boolean{
return this.condition1 && this.condition2 && this.condition3;
}
The only difference is between a function call and evaluating an expression in JavaScript, Angular is irrelevant here. Function call is usually marginally slower, so the first option should be marginally faster.
Angular view compiler produces the following code for updateRenderer function:
function(_ck, _v) {
var _co = _v.component;
---> var currVal_0 = _ck(_v, 3, 0, ((_co.condition1 && _co.condition2) && _co.condition3));
_ck(_v, 2, 0, currVal_0);
}
And
function(_ck, _v) {
var _co = _v.component;
--> var currVal_0 = _ck(_v, 3, 0, _co.shouldDisableField());
_ck(_v, 2, 0, currVal_0);
}
As you can see only one line is different and that is all that matters.
You can read more about updateRenderer function in the article:
The mechanics of DOM updates in Angular.
Most answers here only mention the difference in performance as marginal.
I don't think this is correct and the performance here can be quiet significant.
Please refer to Phil Parsons great article about this:
Function calls in Angular expressions are killing your apps performance
You should be aware of the performance hit as shown there
Not really, though I would suggest the second, as this is much cleaner and will help with minimising data transfer in templates. Admittedly this may seem insignificant, but its good practice to compartmentalise javascript code, plus it will get the benefit of code minification AND gzip (if enabled on HTTP requests).
However, saying that, if this is an exception case, then the first may be more helpful with for other developers (or yourself) down the track, but I would only use this in a rare case, as the second gives you the ability to update/extend/fix it much easier, particularly if you're likely to re-use the same rule/condition.
With regards to Angular's binding model, I'm not sure if there is much in the way of caching (if that's what you were thinking) or performance that I've personally seen.
Hope that helps.
As explained in above answers, both the approaches will work fine.
<li [ngClass]="{disabledField: condition1 && condition2 && condition3}">Click</li>
<li [ngClass]="{disabledField: shouldDisableField()}">Click</li>
But there are some points which make them different.
One of the most important things is AOT strategy. Function calls may be a headache while migrating from JIT to AOT (which normally happens with most of the developers). If the called function is a private function, AOT Compilation throws a compile time error as it treats template and component as 2 different entities.
The other point is, data bindings are readable and can be understood easily.
Having said that, we may come across a situation, where data bindings alone wont solve the problem. Calling a function in those cases wouldn't be a wrong thing to do!
Hope this helps you! :)
There is not really a difference. I would use
<li [ngClass]="{disabledField: condition1 && condition2 && condition3}">Click</li>
if i'd only one expression like that in my template. Otherwise I'd use
<li [ngClass]="{disabledField: shouldDisableField()}">Click</li>
to reduce the written code.

Why test char equals the same char?

Reading through some JavaScript from an ecommerce hosting company and came across this:
function add_wishlist()
{
if ('1' == '1') // <-- What is this?
{
window.open('addtowishlist.asp?itemid=137','popup','height=300,width=550,location=no,scrollbars=no,menubars=no,toolbars=no,resizable=yes');
}
else
{
document.add.action = "add_cart.asp?action=addWishList";
document.add.submit();
}
}
From my basic understanding of JavaScript, the == equality operator will attempt type conversion if required then compare the values. In this case, the character 1 compared to the character 1, which seems like it will always be true.
I feel I might be missing something because why have an else clause if the code is always unreachable? This appears to have been purposeful code as I can't imagine it's easy to accidentally write this comparison. However, there does appear to be some inherent sloppiness to this code since JavaScript programmers should be in the habit of writing curly braces on the same line to avoid any possible semicolon insertion quirks...
Am I missing something here? Or is it just sloppy code?
Sometimes always true statements are used by developers to temporarily disable a branch of code. IMO, comments are a better way to do this.
Another possibility is that this is code generated by a tool, and this is the emitted code they got when disabling a feature.

Question mark syntax from CoffeeScript without CoffeeScript

CoffeeScript has such syntax sugar:
item.getFoo?().fooParam?.bar
Which translates into long javascript equivalent with getFoo==null and fooParam==null checks. The question is: are there any ways to use this syntax in vanilla javascript with a library/translator/compiler other than CoffeeScript? We use Traceur in our project, but it doesn't have such syntax because it is not ES6 compliant (although I wish it to). Maybe some way to implement it within Traceur fork?
If you don't want the exact CoffeeScript semantics, you can cheat a bit:
return item.getFoo ? (item.getFoo().fooParam || {}).bar : undefined;
There are a few tricks going on here.
The ternary operator is used to test the truthiness of item.getFoo
If fooParam is missing, falsey, or absent, we substitute it with an empty object. CoffeeScript would have bailed out here.
We return the value of bar regardless of whether it exists. If it does exist, you get the value you want. If it doesn't exist but fooParam is set, you get undefined. If it doesn't exist because fooParam was undefined and we fell back to {}, you still get undefined.
You can write some helpers if the ternary operator gets in the way:
function defaultObject(input) { // A helper to put somewhere
return input || {};
}
return defaultObject((item.getFoo || defaultObject)().fooParam).bar;
This is even trickier: defaultObject will return {} when called with getFoo, so you don't need a ternary operator around the function call. If fooParam isn't truthy, defaultObject will return another empty object, eliminating the need for another ||. If fooParam is truthy, defaultObject behaves like the identity function and returns it.
I'm sure this could be golfed further down, but I'd recommend avoiding this pattern. Anyone reading your code will be fairly confused and blame you for making a mess in the codebase.
I had this same question recently, and I came here hoping for a better solution than my current one. If you're doing this frequently, it's easier to make a function to do it for you:
var qm = function(arg) {
if (arg instanceof Object) return arg;
return function(){};
};
Then to use it, you wrap your objects in it to make sure no error is raised. It starts to look ugly if there are many question marks on a line
qm(qm(item.getFoo)().fooParam).bar
The optional chaining operator ?. was introduced in ES2020.
obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)
It is supported by the browsers of 91.81% of internet users as of 29 November 2021 according to https://caniuse.com/mdn-javascript_operators_optional_chaining.

New way to write the if statement

I found a way to write the if statement in another way (I think) while searching in the source code of a website.
Instead of:
if(a)b;
or:
a?b:'';
I read:
!a||b;
Is the third way the same as the first two? And if yes, why we would use the third way?
The third way is the same as the previous ones. One argument to use it is saving bytes. A strong argument against using it is readability. You'd better focus on readability in writing code, and use a minimizer (such as Google Closure Compiler) to save bytes.
It can be even shorter:
a && b;
/* !a||b means:
(not a) OR b
which is equivalent to
a AND b
which turns out to be
a && b
*/
Welcome to the concept of short-circuit evaluation. This is well known property of logical operators, employed in different languages. Most often this'll be used as subexpression inside proper if or any other flow control statement, or to express condition short enough so it retains readability in this way, or by automatic transformation to save bytes.
There's even tag for question regarding those: short-circuiting.
The result of the boolean expression sometimes can be evaluated without evaluating all the sub-expressions. If we have A||B, and A is true there's no need to even evaluate B, because the result will be true anyway. This behavior is called "shortcut boolean evaluation" and is defacto standard in most programming languages. It allows to write expressions like if (i < A.length && A[i] == ...) without evaluating the A[i] operand which can lead to an exception if i value is incorrect.
In this particular case, !a||b is the same as if(a)b, yes, but the readability and maintainability of such code is a question though.

Conditional Operators in Javascript

Is it ok to use conditional operators like a statement like so?
(x == y) ? alert("yo!") : alert("meh!");
Or is it more correct to use it to assign a value like so?
z = (x == y) ? "yo!" : "meh!";
If it's not incorrect to use it like a statement, then is it possible to add more than one line of code for execution like so? Is it more correct to use ifthen and switch statements for multiple lines of code?
(x == y) ? (alert("yo!"), document.write("woot!")) : (alert("meh!"), document.write("blah!"));
Conditional operators are intentionally succinct and especially useful for assignments:
var a = x ? 1 : 2;
Using them to conditionally run functions, while possible, should, for the sake of readability be done using IF/ELSE statements:
// This is possible but IMO not best practice:
X ? doSomething() : doSomethingElse();
While long-winded, most of the time, this is the better solution:
if (X) {
doSomething();
} else {
doSomethingElse();
}
One notable benefit to the IF/ELSE structure is that you can add additional tasks under each condition with minimal hassle.
Your last snippet is also possible but it looks somewhat long-winded and, again, might be better suited to a more conventional logical structure; like an IF/ELSE block.
That said, a conditional operator can still be readable, e.g.
(something && somethingElse > 2) ?
doSomeLongFunctionName()
: doSomeOtherLongFunctionName();
In the end, like many things, it's down to personal preference. Always remember that the code you're writing is not just for you; other developers might have to wade through it in the future; try and make it as readable as possible.
JavaScript won't prevent you from doing it, but it's very a unusual practice that will confuse anyone reading your code.
The conditional operator is almost always used for selecting two alternative values, not statements. An if statement is preferred for conditional branching of statements.
As to your last question, yes, if you really must, you can abuse the [] construct:
(x == y) ? [alert("yo!"), document.write("woot!")] : otherstuff();
But please don't. 8-)
It is entirely up to you, you can do it either way. You just have to ask yourself, though, does this style follow company guidelines, and how readable do you want this code to be?
Using if statements is way more readable.
Personally, I only use the ternary operator for simple and quick true/false conditions--where doing so makes sense--or where I need something "inline".
Either of the two methods are acceptable although you could have also written:
alert((x == y) ? "yo!" : "meh!");
Aside from that I would never recommend using an inline conditional for multiline statements, just use a standard if/else block. Given the syntax you entered isn't valid JS either, you could have placed the multiple statements into anonymous methods and yada yada, then you enter into a tangled mess of nearly unmanageable and unnecessarily difficult code. So again, standard if/else.
I agree with both Chris and J-P that:
Conditional operators are handy for short statements. J-P's variable assignment is a great example: var a = x ? 1 : 2;
Multi-statement clauses should be separated on to separate lines, for readability.
Conditional operators can be made readable as multiline statements with the right indentation, but if/else syntax is much more familiar to most developers. Readability is about matching the expectations of your reader, so familiarity is important.
I will add that multi-line conditional operators leave you open to semicolon insertion errors. Check out the JSLint documentation (see the section on "Line Breaking") for more on this. If you must use a multi-line conditional operator, make sure operators are at the end of each line. I would rework J-P's multi-line example thusly:
(something && somethingElse > 2) ?
doSomeLongFunctionName() :
doSomeOtherLongFunctionName();
As has been mentioned, there are many style guides out there and you can choose whichever you prefer. Some choices are more error-prone than others, however. Definitely take a close look at that JSLint documentation; it is a very well-thought-out style guide, and if you adhere to it, you can even use the JSLint tool to automatically check your code for potential problems.

Categories