I had read in some articles that in some languages, like in JavaScript, assignment operators can be used in conditional statements. I want to know what is the logic behind that operation? As far as I know, only comparison operators are allowed in condition checking statements.
Any expression is allowed in a condition checking statement. If the value of the expression isn't boolean, then it will be converted to boolean to determine what the statement should do.
You can for example use a number in an if statement:
if (1) { ... }
Any non-zero number will be converted to true.
In Javascript an assignment is also an expression, i.e. it has a value. The value of the expression is the same value that was assigned to the variable.
So, you can use an assignment expression in a condition checking statement, and the value of the expression is converted to boolean if needed:
if (x = 1) { ... }
Using an assignment in an condition checking statement can be useful, if the value that you assign should be used to control what happens. If you for example have a function that returns different values for the first calls, then a null when there are no more values, you can use that in a loop:
while (line = getLine()) {
document.write(line);
}
You can of couse do that with the assignment separated from the logic, but then the code gets more complicated:
while (true) {
line = getLine();
if (line == null) break;
document.write(line);
}
In JavaScript (and many other languages), when a value is assigned to a variable, the value "returned" is the value that was assigned to a variable. As such, such a statement can be used in a condition with any assigned value being evaluated in the standard way.
For example:
var y = 0;
if(x = y){
alert("Y(and thus X) is Truthy");
}
else{
alert("Y(and thus X) is Falsy");
}
There are two factors that combine to give this effect:
in many languages, including JavaScript, an expression of the form left = right evaluates to the new left. For example, a = b = c = 0 sets all of a, b, and c to zero.
in many languages, including JavaScript, a wide variety of values can be used as conditional expressions. if(7) is equivalent to if(true); so if(a = 7) is equivalent to a = 7; if(true) rather than to the presumably-intended if(a == 7).
Assigning a value with = returns that value. You can use it to make an assignment while testing if the outcome is truthy or falsey (null, 0, "" undefined, NaN, false)
if (myVar = myArgument) ...
//same as:
// myVar=myArgument;
// if (myArgument) ...
This assigns myArgument to myVar while testing myArgument. Another more specific example:
If (myVar = 3+2) ...
// same as:
// myVar=3+2;
// if (5) ...
The benefit is more compact, terse code, sometimes at the expense of clarity.
This could be used to make a condition check and also use the value after it, without writing more lines.
if (value = someFunction()) {
...
}
This is valid syntax, though highly discouraged. In quite a few languages this is explicitely forbidden, but some languages also does not make this rule (e.g. C).
Related
hope you can help. I've got an empty array in my project which fill up as certain buttons are pressed (using push()). I want to know when a certain set of elements are in the array.
In the below code, it seems to work, the 3 elements are all in the array so it prints 'yes'. If I take out the last element ("TR"), it prints 'nope'. However, if I take out either of the first 2 elements, it prints 'yes'. It seems to be only focusing on the last element in the includes() function.
Is there any way to have the include() or something similar, check to see if all elements are in my array? Keep in mind that the array could have many more elements and they won't be sorted.
Thanks in advance.
var arr = ["TL", "TM", "TR"];
if (arr.includes("TL" && "TM" && "TR")){
console.log("yes");
} else {
console.log("nope");
}
The issue is in your if statement because includes() returns a boolean based on the string parameter. A better way of doing this would be to use something like:
if(arr.includes("TL") && arr.includes("TM") && arr.includes("TR")) {
console.log("yes");
}
If you have lots of elements in your array I would suggest something more along the lines of:
var flag = true;
for(i=0; i<arr.length; i++) {
if(!arr.includes(arr[i])) {
flag = false;
}
}
if(flag) {
console.log("yes");
}
Even though the above answers show methods to get your desired result, I'm surprised no one has addressed why your original attempt didn't work. This gets into some foundational rules that JavaScript follows: how functions are called, logical operator evaluation, and operator precedence.
Calling arr.includes()
First off, you have a function includes which takes a single string argument. You have given this argument an expression instead of a string, so it is going to evaluate the expression. If the evaluation produces a string, it will return that value. If it produces a different type, it will attempt to convert the result to a string. So to clear it up, you haven't given it 3 strings to look for, but one expression that will be evaluated and become the string you are looking for.
Logical Operator Evaluation
But what is the value of that string? In JavaScript, the logical operators work in a way that can shortcut and return one of the values being evaluated. In most cases, we'd be comparing boolean values, and get true or false from the evaluation, but we're working with strings here, not booleans. Strings in JavaScript can be evaluated as "truthy" or "falsy", the former being any string that has length and the latter being a string with no length (an empty string). With this in mind, the shortcut functionality of the logical AND && operator will look at the first value in the expression, and if that value is "falsy" it will return that value. If that value is "truthy" it will look at the other side of the expression and return its value.
MDN describes this logic pretty well. Given expr1 && expr2 here's the logic:
Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Order Precendence
Finally, a note on order precedence. Logical AND && is of equal precendence to itself, so your expression will read from left-to-right. If, say, your expression was "TL" || "TM" && "TR" the "TM" && "TR" expression would be evaluated first since logical AND && has a higher precendence than logical OR ||.
Evaluating Your Expression
Knowing all of this, we can pick apart what your expression is doing:
"TL" && "TM" && "TR" is comprised of all logical AND operators, so we will read this from left-to-right, starting with "TL" && "TM". Since "TL" is a truthy string, the other side of the expression is returned which is "TM". The next expression is then "TM" && "TR", of which "TM" is a truthy value, so "TR" is returned. In the end, the includes function is checking if the value of "TR" exists in the array, and ultimately returns true.
Again, do mark one of the others as answers here. Looping through the values you want to search for in the array is what you're looking for, and writing your own loop or using reduce accomplishes that, but I wanted to explain why your initial attempt probably seemed odd and clear up just what was happening.
This can be done cleanly using the reduce method of arrays. Here's how to do it with your example:
var arr = ["TL", "TM", "TR"];
var fails = ["TL"] // This will return false
var succeeds = ["TL", "TM", "TR"] // This will return true
var includesAll = (array_to_check) => arr.reduce(
(accumulator, current) => accumulator && array_to_check.includes(current),
true
)
if (includesAll(succeeds)){
console.log("yes");
} else {
console.log("nope");
}
This function counts number of all characters of a string into a string. I am not fully understanding the if statement here and how it works.
function getFrequency(string) {
var freq = {};
for (var i=0; i<string.length;i++) {
var character = string[i];
if (freq[character]) {
freq[character]++;
} else {
freq[character] = 1;
}
}
return freq;
};
I thought freq[character] is the property of the object such as A B how does it work with if(freq[character]) also how does the increment of freq[character]++ works?
I have made test like this to try and understand it.
var v = {};
v.h = 3;
v["h"]++;
v["h"] = v["h"] + 1;
v.h++;
v.h = v.h + 2;
console.log(v);
console.log(v["h"]);
I think I can guess the if statement works that if the property exists but I thought JS has an object property calls .hasOwnProperty shouldn't this be used instead?
As for the increments, to my test, it works but I just don't get the reason.
Can someone give me a hand to elaborate this?
Thanks in advance
In javascript, objects are associative arrays. And vice versa. There is no difference between the two concepts.
So defining this variable as an empty object:
var freq = {};
... is actually creating an associative array (like a dictionary or map) with no keys added yet.
Moving on, let's take an input string like eek. The code here will look at the first letter and treat freq[character] the same as freq['e'], which is the same as freq.e.
In this code, the initial value of any letter in the freq object is undefined. So that initial if() check for the first "e" in our string actually looks like this:
if(undefined)
Javascript has the concept of "truthy" and "falsy" values; anything in javascript can be evaluated as a boolean, and (in most cases) a sensible result is achieved. Looking at undefined, Javascript will simply treat this a falsy value, fall to the else block, and therefore execute this code:
freq[character] = 1;
As already established, this is the same thing as freq.e = 1;
Now when the loop continues to the next letter (also an "e"), javascript will end up evaluating the expression if (1). Javascript treats this and all other non-zero numbers as "truthy", so this time will execute the following line:
freq[character]++;
Again, that's the same as freq.e++, where freq.e had a value of "1" that can now be incremented to "2".
One more time through the loop for the final letter "k". This time we get freq.k, which is still undefined. Undefined is falsy, so control falls to the else block, and freq.k is set to "1".
Now you can see how we can start to increment letters in the array as you find them in the string, even though it appears that you never defined an array in the first place, never set any values to anything other than "undefined", and never had a real boolean value to check against.
if (freq[character]) checks if the value is "truthy". That is, it's not false, null, undefined or 0. The first time we encounter any character the value will be undefined, since the object literal is created empty, so the "truthy" check will fail and control will fall to the else block.
So when we first see a specific letter set the value to 1 (which is now "truthy").
Any subsequent encounters of that letter just increment the value, which would be equivalent to say freq[character] = freq[character] + 1;. The increment syntax is just a shorthand.
if (freq[character]) checks if the object freq has a property on it with the value of character as the name. The result of this expression evaluates to true or false.
It can be more explicitly stated, as the following non-exhaustively illustrates:
if (freq[character] == null)
or
if (typeof freq[character] === 'undefined')
The danger in not being explicit when evaluating if an object is undefined or null, is if it is actually set to a different type that evaluates to true or false (0, 1, '0', true, false).
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
In PHP you could write this:
if(false !== ($value = someFunctionCall())) {
// use $value
}
How would you write an equivalent of this in JavaScript without defining
var value;
before this comparison?
You'd write
if (value = someFunction()) {
I don't trust my knowledge of PHP that heavily, but I suspect that explicit comparisons to false in if statements aren't necessary, as the expression is implicitly boolean. (edit — sometimes, if a function can return either an explicit boolean or some "good" value that evaluates to "falsy", then yes you do need the explicit comparison to boolean.)
edit — if you're squeamish about the ages-old confusion (or potential thereof) between = and ==, then I'd advise avoiding the construct entirely. There's nothing wrong with it, other than the fact that sometimes you want an equality comparison and sometimes you want an assignment.
edit oh also this presumes that "value" has been declared with var somewhere — if the question is about how you do the declaration in the context of an if statement, then the answer is that you cannot do that.
final edit I kind-of promise — to sum it up:
Assuming that "value" is declared:
var value;
somewhere, then:
if (false !== (value = someFunction())) { ... }
has pretty much the same semantics as the PHP original.
You can just have it assign when it's executed and JavaScript will automatically add the var declaration:
function foo(){
return (Math.random() * 0.5) > 0;
}
if (false !== (f = foo())){
alert('True!');
}
alert('f=' + f.toString());
jsFiddle Example
However, this is very bad practice. You should always declare your variables when and where you need them first. Just because PHP and JS accept this syntax doesn't mean it's good practice. The proper style would be as follows:
var f = false;
if (false !== (f = foo())){
alert('True!');
}
alert('f=' + f.toString());
That would be very bad practice in JavaScript,
You would be best to do
if(!(var value = someFunctionCall())) { // use value //}
Personally i would say define it before. Your call though. If you worried about memory then define it and null it after use.
At wtfjs, I found that the following is legal javascript.
",,," == Array((null,'cool',false,NaN,4)); // true
The argument (null,'cool',false,NaN,4) looks like a tuple to me, but javascript does not have tuples!
Some quick tests in my javascript console yields the following.
var t = (null,'cool',false,NaN,4); // t = 4
(null,'cool',false,NaN,4) === 4; // true
(alert('hello'), 42); // shows the alert and returns 42
It appears to behave exactly like a semicolon ; separated list of statements, simply returning the value of the last statement.
Is there a reference somewhere that describes this syntax and its semantics? Why does it exist, i.e. when should it be used?
You are seeing the effect of the comma operator.
The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand.
The resultant value when a,b,c,...,n is evaluated will always be the value of the rightmost expression, however all expressions in the chain are still evaluated (from left to right).
As already explained this behaviour is caused by , operator. Due to this the expression (null,'cool',false,NaN,4) will always evaluate to 4. So we have
",,," == Array(4)
Array(4) - creates new array with allocated 4 elements. At the time of comparison with the string this array is converted to string like it would be with Array(4).toString(). For arrays toString acts like join(',') method called on this array. So for the empty array of 4 elements join will produce the string ",,,".
Try this alert((null,'cool',false,NaN,4)) and then you can see.
demo
The reason is because the comma operator evaluates all the statements and return the last one.
Think of this line: a = 1, b = 2, c = 3; it will run each expression so in essence it will set the variables to what you want and return the last value (in this case 3)