JavaScript's control flow constructs: browser specific or inherent to JS - javascript

I've put together a little range function in JS. I've tested it in Chrome 19, FF, and IE (7-9) and it's working well. The question I have has to do with the while statement.
function range(from,to,step)
{
'use strict';
var sCode,eCode,result;
result = [];
step = (!step || isNaN(step) || step === 0 ? 1 : step);
sCode = (''+from).charCodeAt(0);
eCode = (''+to).charCodeAt(0);
step *= (sCode > eCode && step > 0 ? -1 : 1);
do
{
if (String.fromCharCode(sCode))
{
result.push(String.fromCharCode(sCode));
}
}while((step > 0 && eCode >= (sCode+=step)) || (step < 0 && eCode <= (sCode+=step)));
return result;
}
I remember reading a question here a while back on how JS handles Control flow constructs and logical operators. I think it had something to do with checking if an object had a certain method, and if so, using it's return value (if (event.returnValue && e.returnValue === true) kind of stuff).I can't seem to find that question any more, here's what I wanted to know:
while((step > 0 && eCode >= (sCode+=step)) || (step < 0 && eCode <= (sCode+=step)));
Since the function behaves as I want it to, I think I'm right in saying that, if step < 0 is false, && eCode >= (sCode+=step) will be ignored, leaving the value of sCode unchanged. When the step check is true, sCode will be in/decremented. I've put this assignment in brackets, to make sure that the newly assigned value of sCode will be compared to eCode. Again, I assume that the brackets will give priority to the assignment over the logical operator.
Is this true for ALL browsers, or is it browser specific to some extent? is there a chance that this function will increment (or decrement) the value of sCode twice in some browsers?In this case, it's not that important (it's an easy fix to prevent any issues). But I want to know if this behaviour is inherent to JavaScript itself, or to the browser implementation.
Thanks for reading this far down. If you don't mind
A couple of other things (not important, but just wondering):
what is the max charCode in JavaScript? A quick look on google didn't tell me, and testing in the JS console lead me to believe this was 5999999999989759 which seems almost incredible, but then again I might need to brush up on my Chinese.
When from is undefined, the (jslint approved) approach from.toString().charCodeAt(0); fails, because obviously, undefined had no toString method, why the, does (''+from).charCodeAt(0); return U all the same? I thought it implicitly called the toString method?

I think I'm right in saying that, if step < 0 is false, && eCode >=
(sCode+=step) will be ignored, leaving the value of sCode unchanged
Correct. If the first operand evaluates to false, the second operand will not be evaluated.
After when the step check is true, sCode will be in/decremented. I've
but this assignment in brackets, to be sure that the newly assigned
value of sCode will be compared to eCode. Again, I assume that the
brackets will give priority to the assignment over the logical
operator.
Correct again, but the parentheses around the assignment are required, since assignment has a lower precedence than a comparison.
Is this true for ALL browsers?
Yes. I would be incredibly suprised if you find one that doesn't behave this way.
When from is undefined, the (jslint approved) approach
from.toString().charCodeAt(0); fails, because obviously, undefined had
no toString method, why the, does (''+from).charCodeAt(0); return U
all the same?
Because it concatenates the value of from with the empty string. The value of from is undefined, which is coerced to a string, and you end up with the string "undefined", and the character at index 0 of that string is "u".

The behavior of operators is consistent for all correct implementations of ECMAScript. I'm not aware of any browser implementation that deviates from what you've described.
ECMAScript is defined by standard. http://ecmascript.org/
And yes, the parentheses will define associativity of the operators..
MDN Operator Precedence

Related

Why is test >= 0 true when test is null?

Let's say I have the following javascript code:
const test = null
if ( test >= 0 ){
console.log("Hello World")
}
This code will print Hello World... In my mind, it should work only if test === null. But all the times that I use the condition test >= 0 the code falls on it. Is there any reason why it happens? I see it as a problem in some situations... For example on the next code:
const test = null
if ( test >= 0 ){
console.log("1")
}
else if ( test === null ){
console.log("Hello World")
}
In this case, the code is not doing what apparently it should be doing. The workaround to make it work would be having the habit of always putting the === null condition at first on if/else or switch/cases. Is that how I'm supposed to work with Javascript? Or is there a better way of doing it?
Is there any reason why it happens?
Any value that is compared to a number will be coerced to a number1. Number(null) is 0, and 0 >= 0 is true. If you had used undefined on the other hand, you'd have gotten NaN >= 0 which is false.
1: In fact, the only non-numeric relational comparison is between two strings (or two objects that convert to strings).
The workaround to make it work would be having the habit of always putting the === null condition at first.
Yes, that's how to deal with variables that can have the value null.
Or is there a better way of doing it?
You might want to avoid having the value null at all in your variable. Depending on the application, whatever the value is representing, could also be expressed as 0 or -1 maybe? Those may not be much cleaner, but they would at least have predictable behaviour in >= 0.
I thought it was a simple question but I was wrong.
I went check ECMAScript Language Specification, which specified how "a>=b" works.
It turned out it is not doing "a>b || a==b", but instead, it is returning the oppsite answer of "a<b".
I think that is why (null >= 0) is returning true, because (null < 0) is returning false.
ES3 spec
11.8.4 The Greater-than-or-equal Operator ( >= ) The production RelationalExpression : RelationalExpression >= ShiftExpression is
evaluated as follows:
Evaluate RelationalExpression.
Call GetValue(Result(1)).
Evaluate ShiftExpression.
Call GetValue(Result(3)).
Perform the comparison Result(2) < Result(4). (see 11.8.5).**
If Result(5) is true or undefined, return false. Otherwise, return true.
And, I found another reference which plots the Relational and Equality Operators of some special cases.
Relational and Equality Operators
if you cast null to bool, you are getting 0.
if ( test >= 0 ){
Here larger or equal operator using for comparison, so you are getting correct results.
For example
Boolean(null); // false
For more please check https://javascript.info/ifelse#boolean-conversion

What's the purpose of str.indexOf(var && var)?

I've found in a library that I'm using this piece of code:
item[column.field].indexOf(columnFilters[columnId] && columnFilters[columnId]) === -1)
and I'm wondering what's the purpose of passing the same value twice to indexOf. Or is it just a mistake and I can correct it.
Library: https://github.com/6pac/SlickGrid/blob/master/examples/example16-row-detail.html (live http://6pac.github.io/SlickGrid/examples/example16-row-detail.html)
Frankly it almost certainly doesn't make any sense there. columnFilters[columnId] && columnFilters[columnId] is effectively the same as columnFilters[columnId] except that columnFilters[columnId] may get evaluated twice (if it's falsy). Unless columnFilters has an accessor property with the name in columnId that has a side effect, && is completely pointless there. (If it does, it'll cause its side effect twice if the result is falsy.)
&& evaluates its left-hand operand and, if it's falsy, takes that value as its result; if the left-hand operand evaluates truthy, && evaluates the right-hand operand and takes that value as its result. So you can see why it's pointless in this case unless it's being used for side-effects from accessors, in which case it's just...a bad idea. :-)
It is the same if you write it just once like this indexOf(columnFilters[columnId])

Purpose of redundant conditions in if-then clause with && (and) operator?

I don't understand the following if-then-else clause, which I found in a piece of code I'm working on.
if (prefstocking && prefstocking >0) {
...
} else {
...
}
Why does the variable prefstocking appear on both sides of the logical operator &&? I thought using the logical operator && meant using both of them, like this: if (x && y = 1) makes sense to me, meaning "if x equals 1 and y equals 1", but what is the meaning of using the same value twice?
Written in plain English, this test reads:
if prefstocking is truthy and its value is greater than 0
however, because most values are truthy, the former check is unnecessary. Any case which fails the first condition would also fail the second. I see a lot of developers write these kind of checks to be extra-sure, but it tells me that they simply aren't thinking about what they're doing.
The first part if (prefstocking && ...) checks the var prefstocking for false, null, undefined, 0, NaN, and the empty string.
These are all called "falsy" values.
If prefstocking is "falsy" then it isn't greater than zero and doesn't need to check that.
Another answer goes into some detail about truthy v. falsy in javascript.
In this case it makes no difference if the test is if (prefstocking > 0) because that will always evaluate to the same result as the original, but the principal is often useful, especially to avoid dereferencing a null or undefined object.
var obj1 = someFunction('stuff', 9); // assume it returns an object
var obj2 = getNullObj(); // assume it always returns null
// this is OK if an object is always returned from the someFunction(...) call
if (obj1.hasData()) { }
// this causes an error when trying to call the .hasData() method on a null or undefined object
if (obj2.hasData()) { }
But, because the logical and && and the or || operators short-circuit, testing like this is safe:
if (obj2 && obj2.hasData()) { }
If the first part is false (falsy) it won't try to evaluate the second part because the logical truth is already know - the whole statement is false if the first part of an and is false. This means .hasData() will never get called if obj2 is null or undefined.
If an object is defined but does not have a .hasData() function then this will still cause an error. Defending against that could look like
if (obj2 && obj2.hasData && obj2.hasData()) { }
// ...or...
if (obj2 && typeof obj2.hasData === 'function' && obj2.hasData()) { }
Short-circuiting allows you to check and avoid failure cases, but checking every possible failure could make your code unreadable and perform poorly; use your judgment.
Others are correct in pointing out that the way to read this is (prefstocking) && (prefstocking > 0). The first condition checks whether prefstocking is truthy. The second condition makes sure it's greater than 0. Now, as to why bother doing that? Here I disagree with the other answers.
There are situations in programming where we might use redundant conditions in an if then clause because of efficiency. In this situation, mathematically speaking the first condition is redundant. That is, if the second condition is true, then the first condition is also true. However, order matters. An if an interpreter checks the first condition and finds it false, followed by an && (and), then it doesn't need to test further. And it probably won't test the second condition (see comments below: according to ECMAScript standard, it definitely won't test the second condition). This could be useful if it is less computationally expensive to check the first condition, such as first ruling out null cases. The specifics of whether it's actually more efficient are hard to quantify with JavaScript because the internals are often not specified and each JS interpreter works in its own way.
Also, an expression of the form if (x && y == 1) would be interpreted as "if x is truthy and if y equals 1". You have misunderstood the order of operations. Both sides of the && make separate conditions. They don't combine into one condition like the might in English. This expression certainly does not mean "if x and y equal 1". Make sure you have understood that.

boolean in an if statement

Today I've gotten a remark about code considering the way I check whether a variable is true or false in a school assignment.
The code which I had written was something like this:
var booleanValue = true;
function someFunction(){
if(booleanValue === true){
return "something";
}
}
They said it was better/neater to write it like this:
var booleanValue = true;
function someFunction(){
if(booleanValue){
return "something";
}
}
The remark which I have gotten about the "=== true" part was that it was not needed and could create confusion.
However my idea is that it is better to check whether the variable is a boolean or not, especially since Javascript is a loosetyped language.
In the second example a string would also return "something";
So my question; Is it neater to loose the "=== true" part in the future, or is it good practise to check the type of the variable as well.
Edit:
In my "real" code the boolean represents whether an image has been deleted or not, so the only values boolValue should ever have is true or false.
0 and 1 for example shouldn't be in that variable.
First off, the facts:
if (booleanValue)
Will satisfy the if statement for any truthy value of booleanValue including true, any non-zero number, any non-empty string value, any object or array reference, etc...
On the other hand:
if (booleanValue === true)
This will only satisfy the if condition if booleanValue is exactly equal to true. No other truthy value will satisfy it.
On the other hand if you do this:
if (someVar == true)
Then, what Javascript will do is type coerce true to match the type of someVar and then compare the two variables. There are lots of situations where this is likely not what one would intend. Because of this, in most cases you want to avoid == because there's a fairly long set of rules on how Javascript will type coerce two things to be the same type and unless you understand all those rules and can anticipate everything that the JS interpreter might do when given two different types (which most JS developers cannot), you probably want to avoid == entirely.
As an example of how confusing it can be:
var x;
x = 0;
console.log(x == true); // false, as expected
console.log(x == false); // true as expected
x = 1;
console.log(x == true); // true, as expected
console.log(x == false); // false as expected
x = 2;
console.log(x == true); // false, ??
console.log(x == false); // false
For the value 2, you would think that 2 is a truthy value so it would compare favorably to true, but that isn't how the type coercion works. It is converting the right hand value to match the type of the left hand value so its converting true to the number 1 so it's comparing 2 == 1 which is certainly not what you likely intended.
So, buyer beware. It's likely best to avoid == in nearly all cases unless you explicitly know the types you will be comparing and know how all the possible types coercion algorithms work.
So, it really depends upon the expected values for booleanValue and how you want the code to work. If you know in advance that it's only ever going to have a true or false value, then comparing it explicitly with
if (booleanValue === true)
is just extra code and unnecessary and
if (booleanValue)
is more compact and arguably cleaner/better.
If, on the other hand, you don't know what booleanValue might be and you want to test if it is truly set to true with no other automatic type conversions allowed, then
if (booleanValue === true)
is not only a good idea, but required.
For example, if you look at the implementation of .on() in jQuery, it has an optional return value. If the callback returns false, then jQuery will automatically stop propagation of the event. In this specific case, since jQuery wants to ONLY stop propagation if false was returned, they check the return value explicity for === false because they don't want undefined or 0 or "" or anything else that will automatically type-convert to false to also satisfy the comparison.
For example, here's the jQuery event handling callback code:
ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );
if ( ret !== undefined ) {
event.result = ret;
if ( ret === false ) {
event.preventDefault();
event.stopPropagation();
}
}
You can see that jQuery is explicitly looking for ret === false.
But, there are also many other places in the jQuery code where a simpler check is appropriate given the desire of the code. For example:
// The DOM ready check for Internet Explorer
function doScrollCheck() {
if ( jQuery.isReady ) {
return;
}
...
If you write: if(x === true) , It will be true for only x = true
If you write: if(x) , it will be true for any x that is not: '' (empty string), false, null, undefined, 0, NaN.
In general, it is cleaner and simpler to omit the === true.
However, in Javascript, those statements are different.
if (booleanValue) will execute if booleanValue is truthy – anything other than 0, false, '', NaN, null, and undefined.
if (booleanValue === true) will only execute if booleanValue is precisely equal to true.
In the plain "if" the variable will be coerced to a Boolean and it uses toBoolean on the object:-
Argument Type Result
Undefined false
Null false
Boolean The result equals the input argument (no conversion).
Number The result is false if the argument is +0, −0, or NaN;
otherwise the result is true.
String The result is false if the argument is the empty
String (its length is zero); otherwise the result is true.
Object true.
But comparison with === does not have any type coercion, so they must be equal without coercion.
If you are saying that the object may not even be a Boolean then you may have to consider more than just true/false.
if(x===true){
...
} else if(x===false){
....
} else {
....
}
It depends on your usecase. It may make sense to check the type too, but if it's just a flag, it does not.
If the variable can only ever take on boolean values, then it's reasonable to use the shorter syntax.
If it can potentially be assigned other types, and you need to distinguish true from 1 or "foo", then you must use === true.
The identity (===) operator behaves identically to the equality (==) operator except no type conversion is done, and the types must be the same to be considered equal.
Since the checked value is Boolean it's preferred to use it directly for less coding and at all it did same ==true
Since you already initialized clearly as bool, I think === operator is not required.
I think that your reasoning is sound. But in practice I have found that it is far more common to omit the === comparison. I think that there are three reasons for that:
It does not usually add to the meaning of the expression - that's in cases where the value is known to be boolean anyway.
Because there is a great deal of type-uncertainty in JavaScript, forcing a type check tends to bite you when you get an unexpected undefined or null value. Often you just want your test to fail in such cases. (Though I try to balance this view with the "fail fast" motto).
JavaScript programmers like to play fast-and-loose with types - especially in boolean expressions - because we can.
Consider this example:
var someString = getInput();
var normalized = someString && trim(someString);
// trim() removes leading and trailing whitespace
if (normalized) {
submitInput(normalized);
}
I think that this kind of code is not uncommon. It handles cases where getInput() returns undefined, null, or an empty string. Due to the two boolean evaluations submitInput() is only called if the given input is a string that contains non-whitespace characters.
In JavaScript && returns its first argument if it is falsy or its second argument if the first argument is truthy; so normalized will be undefined if someString was undefined and so forth. That means that none of the inputs to the boolean expressions above are actually boolean values.
I know that a lot of programmers who are accustomed to strong type-checking cringe when seeing code like this. But note applying strong typing would likely require explicit checks for null or undefined values, which would clutter up the code. In JavaScript that is not needed.
In Javascript the idea of boolean is fairly ambiguous. Consider this:
var bool = 0
if(bool){..} //evaluates to false
if(//uninitialized var) //evaluates to false
So when you're using an if statement, (or any other control statement), one does not have to use a "boolean" type var. Therefore, in my opinion, the "=== true" part of your statement is unnecessary if you know it is a boolean, but absolutely necessary if your value is an ambiguous "truthy" var. More on booleans in javscript can be found here.
Also can be tested with Boolean object, if you need to test an object
error={Boolean(errors.email)}
This depends. If you are concerned that your variable could end up as something that resolves to TRUE. Then hard checking is a must. Otherwise it is up to you. However, I doubt that the syntax whatever == TRUE would ever confuse anyone who knew what they were doing.
Revisa https://www.w3schools.com/js/js_comparisons.asp
example:
var p=5;
p==5 ? true
p=="5" ? true
p==="5" ? false
=== means same type also same value
== just same value

Using Logical AND in Javascript Variable Declarations

I am interested in the practical application of declaring variables using && like this:
var x = undefined && 4;
// Evaluate to the first falsey value
// or else the last value.
eval(x);
// undefined
I understand how the value is evaluated (see this SO answer). I also understand its sister || (see here for a great description) and why it would be useful to declare a variable with the following expression:
// Some other variable
var y;
var x = y || 4;
// Evaluate to the first truthy value
// or else the last value.
Practically: Use the first value unless that first value is falsey; if so, use the last value. We can demonstrate this characteristic of || in the browser console:
> null || 4
4
> 4 || null
4
> null || undefined
undefined
> undefined || null
null
> true || 4
true
> 4 || true
4
As for &&:
> null && 4
null
> 4 && null
null
> null && undefined
null
> undefined && null
undefined
> true && 4
4
> 4 && true
true
Should we take this to mean: Use the first value unless that first value is truthy; if so, use the last value?
I'm interested in using coding shortcuts to minimize the use of conditional statements, and I wonder if I might be able to use this one somehow.
I found an example of this coding method in line 472 of the jQuery core source:
scripts = !keepScripts && [];
So the question is this: Can anyone describe a good context for using && in a javascript variable declaration? Do you consider it to be bad practice?
Thanks!
In general, you should only only use "shortcuts" like this if it makes the code more readable for the typical JavaScript programmer than the alternative.
When thinking about what is more readable, and less surprising, consider that
var foo;
if(bar) {
foo=[];
}
and
var foo = bar && [];
are not the same. For instance, if bar is NaN, then foo will then be NaN in the later case, which might be a bit of a head-scratcher later on.
Since there are tools to optimize/minimize JavaScript, you should focus on readability of your code, which is not always the same thing as brevity.
Lets say you have several such repetitive initializations in a row, all dependent on different variables (so that they couldn't be wrapped into a single conditional), but following the same logical formula. In this case, once the reader had mentally parsed the meaning of the formula, they could quickly scan all the instances and see the differences between each one. In this case, instead of relying on a convention that most JavaScript programmers are familiar with (such as var foo = some_opt || {}), you are creating a localized convention, that the reader will have to learn just for this file. Even in this case, I'd advise some careful consideration, its probably not worth it.
I found one specific circumstance in which it can be useful to use && in the debugging process.
Let's say we have a variable x. Sometimes x has a value of null, and sometimes x is an Object with value {'foo':'bar'}. We want to write an expression that returns the value of x.foo if it exists.
However, we have to be careful. Calling a property of an object that does not exist can result in this:
> Uncaught TypeError: Cannot read property 'foo' of null
So we can write this:
x && x.foo
Which does the following:
If x is an Object and x.foo exists, give us the value of x.foo.
If x is an Object and x.foo doesn't exist, return undefined.
If x is null, return null.
As long as x has been mentioned somewhere (even if x is simply set to null or undefined), the expression should not break the code.
Actually, you should not regularly use && operator like Jquery does since it is always risky code. You may forget what you have done or you may not find a bug due to the this usage. I personally consider this as a bad practice. You may prefer to use, but code becomes unreadable. We, developers should think about understandability and readability of the code.
Well, it's a common idiom but maybe it makes your code less readable. So, my suggestion, keep it simple, even if it means a few more keystrokes.

Categories

Resources