Is it valid to use an if clause with .hasClass()?
Example:
if ($(this).hasClass("class")){
this will happen
}
Or
if ($(this).hasClass("class") == true){
this will happen
}
Looking at the source itself of hasClass, we can see that only a boolean can be returned
function (selector) {
var className = " " + selector + " ",
i = 0,
l = this.length;
for (; i < l; i++) {
if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) {
return true;
}
}
return false;
}
Therefore, checking without comparing is valid
if ($(this).hasClass("class")){
It is valid to use an if statement with any expression. The if statement is a control flow statement that either jumps over the immediate block (or single statement) or executes it, depending on the value of the expression inside the statement. Any value will be coerced to Boolean using standard coercion rules.
The == comparison operator evaluates to a Boolean that's true if both both operands are equal (using this algorithm), and false otherwise. A comparison of any value to true is redundant, since if it is true, or is convertible to true, the expression would also be true, and will be false for any other value
In the case of .hasClass(), the return value is already a Boolean so no coercion is required.
So, Yes it's valid, there's no difference between the statements, and you can (and should) use the first.
Related
Today when I was doing some experiments with ==, I accidentally found out that "\n\t\r" == 0. How on earth does "\n\t\r" equal to 0, or false?
What I did is:
var txt = "\n"; //new line
txt == 0; //it gives me true
And that really annoy me. So I did more:
var txt = "\r"; //"return"
txt == 0; //true
var txt = "\t"; //"tab"
txt == 0; //true
It does not make sense, at all. How's that happen? And more crazy is this:
//Checking for variable declared or not
var txt ="\n\t\r";
if(txt!=false){
console.log("Variable is declared.");
}else{
console.log("Variable is not declared.");
}
What it gives me is Variable is not declared.
How is it equal to 0, or false???
This behaviour might be surprising but can be explained by having a look at the specification.
We have to look at the what happens when a comparison with the equals operator is performed. The exact algorithm is defined in section 11.9.3.
I built a simple tool to demonstrate which algorithm steps are executed: https://felix-kling.de/js-loose-comparison/
string == integer
The step we have to look at is #5:
5. If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
That means the string "\n" ("\r", "\t") is converted to a number first and then compared against 0.
How is a string converted to a number? This is explained in section 9.3.1. In short, we have:
The MV (mathematical value) of StringNumericLiteral ::: StrWhiteSpace is 0.
where StrWhiteSpace is defined as
StrWhiteSpace :::
StrWhiteSpaceChar StrWhiteSpace_opt
StrWhiteSpaceChar :::
WhiteSpace
LineTerminator
This just means that the numerical value of strings containing white space characters and/or a line terminator is 0.
Which characters are considered as white space characters is defined in section 7.3.
string == boolean
The step we have to look at is #7:
7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
How booleans are converted to numbers is pretty simple: true becomes 1 and false becomes 0.
Afterwards we are comparing a string against a number, which is explained above.
As others have mentioned, strict comparison (===) can be used to avoid this "problem". Actually you should only be using the normal comparison if you know what you are doing and want this behaviour.
Because JavaScript is a loosely typed language, it attempts to type cast your 1st side of the comparison to the other so that they would match each other.
Any string which does not contain a number, becomes 0 when compared to an integer, and becomes true (Except in certain situations), when compared to a Boolean.
Light reading material.
txt is not a Boolean, so it will never be false. It can be undefined though.
var txt ="\n\t\r";
if(txt !== undefined) { //or just: if (txt)
console.log("Variable is declared.");
} else {
console.log("Variable is not declared.");
}
//=> will log: 'Variable is declared.'
By the way, a declared variable may be undefined (e.g. var txt;).
If you do a stricter comparison (without type coercion, using ===), you'll see that
var txt = '\n'; txt === 0; //=> false
var txt = '\r'; txt === 0; //=> false
var txt = '\t'; txt === 0; //=> false
See also
The reason is that "\n\t\r" just as " " are treated as empty strings.
If you use == it will return true but if you use === it will return false.
If you want to test for existence you should use something like
if(typeof strName !== 'undefined') {
/*do something with strName*/
} else {
/*do something without it*/
}
Whenever you use the == operator and try to compare a string to a number, the string will first be converted to a number. Thus: alert("\n\r"==0) becomes: alert(Number("\n\r")==0)
The Number constructure is kind of interesting. It will first strip whitespace then decide if the number is a not a number or not. If NaN, then the result is "NaN". If the string is empty, then the result is 0.
alert(Number()) alerts 0
alert(Number("")) alerts 0
alert(Number(" \n \r \n \t")) alerts 0
alert(Number("blah")) alerts NaN
alert(Number("0xFF")) alerts 255
alert(Number("1E6")) alerts 1000000
To check if the result is NaN use isNaN()
Thus: alert(isNaN("blah")) alerts true
Thus: alert(isNaN("")) alerts false
Thus: alert(isNaN("\n")) alerts false
Thus: alert(isNaN(" ")) alerts false
however do note that NaN will never equal NaN:
var nan=Number("geh");alert(nan==nan); alerts false
Update:
if you want to check if both sides are NaN, then you'd convert both to boolean values first like so:
var nan=Number("geh");alert(!!nan==!!nan); alerts true
or better yet
var nan=Number("geh");
alert(isNaN(nan)&& isNaN(nan));
I am slightly confused on the logical NOT operator in Javascript (!). From my understanding, this is mainly used to "inverse" a boolean value. For example, if an expected output of a boolean is true, putting this in front would turn it to false, and vice versa.
In my below code, I created a function allowing user to input a lower and upper integer, and the function would generate a random number between this range. If, however, the user inputs a string instead of an integer, it will prompt the user to enter an integer instead.
I am using isNaN to check if user's input is an integer, and using logical NOT operator in front of it to inverse the result.
In my if condition, if I check isNaN for lower && isNaN for upper are both not a number, this program seems to work correctly. However, if I use ||, it doesn't work as expected, as shown in my code below.
Why is this so? By using OR operator, I am saying if either upper or lower is NaN, then prompt the user to enter a valid integer. Why is it a && and not a || when only one condition needs to be true?
const getNumber = function(lower, upper) {
if ( !isNaN(lower) || !isNaN(upper) ) {
const number = Math.floor(Math.random() * (upper - lower + 1)) + lower;
return number;
} else {
alert("Please enter a valid integer.");
}
};
// Call the function and pass it different values
console.log( getNumber('six',5) );
It's not the ! operator that's the problem, it's ||. if ( !isNaN(lower) || !isNaN(upper) ) { says (roughly) "if lower is a number or upper is a number". But you don't wan to say "or" there, because you want them both to be numbers.
So either use use && (and):
if ( !isNaN(lower) && !isNaN(upper) ) {
// −−−−−−−−−−−−−−−−^^
const number = Math.floor(Math.random() * (upper - lower + 1)) + lower;
return number;
} else {
alert("Please enter a valid integer.");
}
or reverse the content of your if and else blocks and use || without !:
if ( isNaN(lower) || isNaN(upper) ) {
alert("Please enter a valid integer.");
} else {
const number = Math.floor(Math.random() * (upper - lower + 1)) + lower;
return number;
}
Side note: You're using implicit string-to-number parsing in your code. I recommend doing it on purpose. My answer here goes into your various options for parsing numbers and their pros and cons.
By using OR, you are checking that at least one value should not be NaN.
let a = !isNaN(lower);
let b = !isNaN(upper);
a and b can be either true or false. When you use ||, you are telling that at least one of this values should be true. If you check Truth table, you will see that OR will be true for this combitations of a and b:
a == true, b == true
a == false, b == true
a == true, b == false
What you want is to check that a == true and b == true simultaneously - so you have to use AND (&&) which will evaluate to true if and only if a == true and b == true.
I've been working on learning JS, and I can't seem to figure out why my boolean values keep coming back either always true or always false.
So I believe I understand the basics of the truthy/falsy situation in JS, but I can't seem to get it right. I know that there are data type issues, (can't make different data types do different things).
function lastCharacter(char1, char2) {
if (char1[-1] === '' && char2[-1] === '') {
return true;
} else {
return false;
}
}
console.log(lastCharacter('apple', 'pumpkine'));
Or
function lastCharacter(char1, char2) {
if (char1[-1] === char2[-1]) {
return true;
} else {
return false;
}
}
console.log(lastCharacter('apple', 'pumpkina'));
Define a function lastCharacter that accepts two strings as arguments.
lastCharacter should return true if both strings end with the same character.
Otherwise, lastCharacter should return false.
They either return always true or always false. Can anyone help me?
You need a different method for getting the last character of a string, preferably with String#slice and a negative value for getting the last one. Then compare and return the result.
function lastCharacter(string1, string2) {
return string1.slice(-1) === string2.slice(-1);
}
console.log(lastCharacter('apple', 'pumpkine'));
A comparison between taking the last character of an empty string by using an index -1 which returns undefined and slice, which returns an empty string.
var x = '';
console.log('#' + x.slice(-1) + '#');
console.log('#' + x[x.length -1] + '#');
You can use slice
function lastCharacter(char1, char2) {
return char1.slice(-1) === char2.slice(-1)
}
console.log(lastCharacter('apple', 'pumpkina'));
console.log(lastCharacter('apple', 'snake'));
Or you can just access the last index
function lastCharacter(char1, char2) {
return char1[char1.length-1] === char2[char2.length-1]
}
console.log(lastCharacter('apple', 'pumpkina'));
console.log(lastCharacter('apple', 'snake'));
There are no negative array indexes in JavaScript, instead of char1[-1] you have to use char1[char1.length - 1].
Accessing one of a strings characters (e.g. "abc[1]) will always have a length of 1, it will never be equal to "". Your second function makes more sense.
Also
if(condition) { return true; } else { return false; }
is equal to
return condition;
The notation [-1] does not implicitly mean "one character from the end of the string" in JavaScript. You can use str[str.length - 1]. (If you expect possible empty source strings, you'd want to check for that too to avoid ending up with exactly the same problem.)
Instead of an if/else that returns either true or false, just return the results of the logical expression:
return char1[char1.length - 1] === '' && char2[char2.length - 1] === '';
Both the === comparisons return either true or false anyway, so the overall expression value has to be one of those. In general however if you want to make absolutely sure that you end up with a boolean, you can prefix an expression with !! to force the standard JavaScript "truthy-falsy" evaluation:
return !!(expression);
I have a simple code:
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#continue").click(function() {
var value = jQuery('#continue').attr('value')
alert (value);
if (value='next'){
jQuery('#msg_title').html('blablabla');
jQuery('#msg').html('blablabla'');
jQuery('#continue').attr('value','removeConfig');
value = jQuery('#continue').attr('value');
}
else if (value='removeConfig') {
jQuery('#msg_title').html('It Works!');
}
else {
alert ('Something wrong')
}
return false;
});
});
</script>
It works well in firs if phase, changes button's value (as I see from alert), but doesn't make else if and else statements.
Your comparison operator is wrong: if (value='next') should be if (value == 'next'){ or if (value === 'next'){.
Note the extra = signs.
You need ==
(value='next'){
should be:
(value == 'next'){
You are testing if ('next') { which is always true. Only string the evaluates to false is empty string, ""
Use ==, not =. A single = is an assignment operator, which means it's assigning "next" to value, then testing if value is false, not if value equals next
You need double equals signs as singles will return true in this case:
if (value =="next")
Single = is an assignment operator and double == is a comparison operator. Since you were using an assignment operator and setting the variable to a non falsy value the first if statement resolved to true.
What does an exclamation mark before a function do?
Example:
return !loadDynamicBlock();
A ! negates an expression.
In your example, if loadDynamicBlock() returned true, the function calling it would return false, and vice-versa: !true == false
It can also be used to create actual booleans from JavaScript's ideas of truthy and falsy.
var a = 5;
!!(a - 5) === false;
!!(a + 5) === true;
The ! in Javascript inverts a boolean expression.