I was checking out JSLint, and some of the rules piqued my interest. Particularly this:
Disallow == and !=
Disallow ++ and --
Why is it a bad idea to disallow these? I understand the first part, basically it wants me to do === instead of ==. I don't understand why though. I understand the difference between the two, I just want to know why is it bad practice. Some times I really want to do == for example so that it would evaluate true for undefined == null
The second one, well I don't understand at all. Does it want me to do myInt += 1 instead of myInt++ ?
Thanks!
I don't agree too much with those rules, instead of discouraging the use of ==, I would recommend to learn about type coercion.
The primary reason about why Crockford wants to avoid == is that the comparison rules depending on the types of the operands can make this operator non-transitive, for example, if:
A == B AND
B == C
Doesn't guarantees that:
A == C
A real example:
'0' == 0; // true
0 == ''; // true
'0' == ''; // false
The strict === operator is not really necessary when you compare values of the same type, for example:
if (typeof foo == "function") { }
We compare the result of the typeof operator, which is always a string, with a string literal...
Another example, when you compare something against null, == also compares against undefined, for example:
if (something == null) {}
VS
if (something === null || typeof something === "undefined") {}
The above two conditions are at the end equivalent, but the first one much more readable, of course if you know about type coercion and how == behaves.
Learning how the == operator works, will help you to wisely decide which to use.
Recommended articles:
ECMAScript. Equality operators (Great tips to remember how == works)
typeof, == and ===
Doug Crockford has his own ideas about what is "good" and "bad" in Javascript. Accordingly, JSLint implements these checks, but makes them optional if you don't completely agree with him.
Disallowing == helps prevent you from making mistakes when you really meant ===. Of course this assumes that you never really want to use ==.
Disallowing ++ and -- is a style thing, some people believe they are harder to read than += 1 and -= 1.
Douglas crockford (the guy who wrote JSLint) explains himself in this video :
http://www.youtube.com/watch?v=hQVTIJBZook#t=14m45s
but basically (as everyone else has mentioned) it's because of the type coercian.
Worth watching the who video to be honest - very interesting and useful.
From the instructions:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors.
and
The ++ (increment) and -- (decrement) operators have been known to contribute to bad code by encouraging excessive trickiness. They are second only to faulty architecture in enabling to viruses and other security menaces. There is a plusplus option that prohibits the use of these operators.
The == and != operators do implicit converson of the operators if needed, while the === and !== operators don't. The expression 4 == '4' for example will be true, while the expression 4 === '4' will be false.
Preferrably you should know the data types you are dealing with, so that you can do the proper comparisons in the code.
The ++ and -- operators doesn't cause any problems if they are used alone in a statement, but they are often used to make a statement that does more than one thing in a not so obvious way, like:
arr[++idx] = 42;
which would be clearer as:
idx += 1;
arr[idx] = 42;
The behavior of the standard equality operators (== and !=) depends on the JavaScript version. So that's one reason for not using them.
Another reason is that the behavior of the = tends to be very vague.
See https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Comparison_Operators
I understand ==. (the undefined == null thing is an exception)
("0" == false) === true
("0" === false) === false
I've never understood the ++ and -- thing though. I don't like doing i+=1 all over my code (it's slower than ++i).
Related
I saw a do-while loop that looked something like
var guess = false;
do {
stuff stuff stufff
if ( things === things){
guess = true;
}
} while ( ! guess )
This confused me because the ! operator changes the boolean value to the opposite, so that guess becomes true instead of false. So "while not false" the do-while keeps running? Or does this mean "while true" it keeps running or...?
thanks for the help!
while(!guess) means "while guess is not true".
It also can be written as while(guess == false). Maybe that way is easier to understand, although it is not a good practice.
There are some examples here: MDN - Logical operators
the actual format would be
if (things == things)
{
coding here......
}
the == mean is equal to.
the >= means greater than or equal too.
the <= means less than or equal to.
the != means that its not equal to.
so if you change the operators this would be
if (things == things) which means things are equal to things.
if (things >= things) which means things is greater than or equal to the things.
Follow the steps and for example when you use this in speech it would look like
if (speech == "things")
{
do coding.........
}
the speech is equal to things then the code will be executed
This is from Crockford's JavaScript: The Good Parts
var is_array = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
};
Would this code have worked just as well if he had used a simple equality compare == instead of the identity compare ===?
My understanding of identity is that it allows you to check if a value is really set to something specific, and not just something equivalent. For example:
x == true
Will evaluate to true if x is 1, or true, but
x === true will only be true if x is true.
Is it ever possible for the is_array function above to work with either == or ===, but not the other?
In this particular case == and === will work identically.
There would be no real difference in this case because both sides of the quality test are already strings so the extra type conversion that == could do won't come into play here. Since there's never any type conversion here, then == and === will generate the same result.
In my own personal opinion, I tend to use === unless I explicitly want to allow type conversion as I think there is less likelihood of getting surprised by some result.
You are correct. With == instead of === it should work fine.
=== is a strict match, and will not return true for 'falsy' or 'truthy' values (see this for more details). Which shouldn't apply in this situation.
Throughout many third-party libraries and best practices blogs/recommendations, etc... it is common to see syntax like this:
typeof x === 'object' (instead of typeof x == 'object')
typeof y === 'string' (instead of typeof x == 'string')
typeof z === 'function' (instead of typeof x == 'function')
If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.
Under what circumstances will typeof not return a string literal? And even if there's some fringe case why is the additional type check being used for object, string, function, etc...
To answer the main question - there is no danger in using typeof with ==. Below is the reason why you may want to use === anyway.
The recommendation from Crockford is that it's safer to use === in many circumstances, and that if you're going to use it in some circumstances it's better to be consistent and use it for everything.
The thinking is that you can either think about whether to use == or === every time you check for equality, or you can just get into the habit of always writing ===.
There's hardly ever a reason for using == over === - if you're comparing to true or false and you want coercion (for example you want 0 or '' to evaluate to false) then just use if(! empty_str) rather than if(empty_str == false).
To those who don't understand the problems of == outside of the context of typeof, see this, from The Good Parts:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
It's subjective. You can just as easily turn this around, and ask, "Why would you use == when you don't expect implicit conversions?" Both work fine here, so use the one you feel expresses your intention better. Try to be consistent within a project.
There's no reason at all to favour === over == in this case, since both operands are guaranteed to be strings and both operators will therefore give the same result. Since == is one character fewer I would favour that.
Crockford's advice on this is to use === all the time, which is reasonable advice for a beginner but pointlessly paranoid if you know the issues (covered in other answers).
Because === is quicker than ==, due to omitting type coercion.
Sure it is probably a negligible difference but it is still there.
Triple equal operators are mostly used for variable type and value checking (all in 1 expression), also known as equality without type coercion.
Example:
var a = 1;
var b = 1;
var c = "1";
var d = "1";
alert (a === b); //True, same value and same type (numeric)
alert(c === d); //True, same value and same type (string)
alert(b === c); //False, different type but same value of 1
See Doug Crockford's YUI Theater on type coercion.
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
The most efficient reason for not using typeof and rather the === operator would be for type coercion (interpretation) between browsers. Some browsers can pass 6=="6" as true and some wouldn't (depending on the strictness of the JS interpreter) so by introducing type coercion would clarify this.
Also, it would bring the "Object-Orientativity" approach to it since JavasScript's variables are not type-based variables (i.e. variable types are not declared on compile time like in Java).
E.g. in Java, this would fail:
if ("6" instanceof Number) { // false
Hope I answered your question.
Recently I was running some of my code through JSLint when I came up with this error. The thing I think is funny about this error though is that it automatically assumes that all == should be ===.
Does that really make any sense? I could see a lot of instances that you would not want to compare type, and I am worried that this could actually cause problems.
The word "Expected" would imply that this should be done EVERY time.....That is what does not make sense to me.
IMO, blindly using ===, without trying to understand how type conversion works doesn't make much sense.
The primary fear about the Equals operator == is that the comparison rules depending on the types compared can make the operator non-transitive, for example, if:
A == B AND
B == C
Doesn't really guarantees that:
A == C
For example:
'0' == 0; // true
0 == ''; // true
'0' == ''; // false
The Strict Equals operator === is not really necessary when you compare values of the same type, the most common example:
if (typeof foo == "function") {
//..
}
We compare the result of the typeof operator, which is always a string, with a string literal...
Or when you know the type coercion rules, for example, check if something is null or undefinedsomething:
if (foo == null) {
// foo is null or undefined
}
// Vs. the following non-sense version:
if (foo === null || typeof foo === "undefined") {
// foo is null or undefined
}
JSLint is inherently more defensive than the Javascript syntax allows for.
From the JSLint documentation:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors.
When comparing to any of the following values, use the === or !== operators (which do not do type coercion): 0 '' undefined null false true
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
The === and !== operators are preferred.
Keep in mind that JSLint enforces one persons idea of what good JavaScript should be. You still have to use common sense when implementing the changes it suggests.
In general, comparing type and value will make your code safer (you will not run into the unexpected behavior when type conversion doesn't do what you think it should).
Triple-equal is different to double-equal because in addition to checking whether the two sides are the same value, triple-equal also checks that they are the same data type.
So ("4" == 4) is true, whereas ("4" === 4) is false.
Triple-equal also runs slightly quicker, because JavaScript doesn't have to waste time doing any type conversions prior to giving you the answer.
JSLint is deliberately aimed at making your JavaScript code as strict as possible, with the aim of reducing obscure bugs. It highlights this sort of thing to try to get you to code in a way that forces you to respect data types.
But the good thing about JSLint is that it is just a guide. As they say on the site, it will hurt your feelings, even if you're a very good JavaScript programmer. But you shouldn't feel obliged to follow its advice. If you've read what it has to say and you understand it, but you are sure your code isn't going to break, then there's no compulsion on you to change anything.
You can even tell JSLint to ignore categories of checks if you don't want to be bombarded with warnings that you're not going to do anything about.
A quote from http://javascript.crockford.com/code.html:
=== and !== Operators.
It is almost always better to use the
=== and !== operators. The == and != operators do type coercion. In
particular, do not use == to compare
against falsy values.
JSLint is very strict, their 'webjslint.js' does not even pass their own validation.
If you want to test for falsyness. JSLint does not allow
if (foo == null)
but does allow
if (!foo)
To help explain this question and also explain why NetBeans (from) 7.3 has started showing this warning this is an extract from the response on the NetBeans bug tracker when someone reported this as a bug:
It is good practice to use === rather than == in JavaScript.
The == and != operators do type coercion before comparing. This is bad because
it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot
reliably determine if == is being used correctly, so it is best to not use ==
and != at all and to always use the more reliable === and !== operators
instead.
Reference
Well it can't really cause problems, it's just giving you advice. Take it or leave it. That said, I'm not sure how clever it is. There may well be contexts in which it doesn't present it as an issue.
You can add this to the previous line to disable these warning.
// eslint-disable-next-line
What is the correct way to check for equality between Strings in JavaScript?
always Until you fully understand the differences and implications of using the == and === operators, use the === operator since it will save you from obscure (non-obvious) bugs and WTFs. The "regular" == operator can have very unexpected results due to the type-coercion internally, so using === is always the recommended approach.
For insight into this, and other "good vs. bad" parts of Javascript read up on Mr. Douglas Crockford and his work. There's a great Google Tech Talk where he summarizes lots of good info: http://www.youtube.com/watch?v=hQVTIJBZook
Update:
The You Don't Know JS series by Kyle Simpson is excellent (and free to read online). The series goes into the commonly misunderstood areas of the language and explains the "bad parts" that Crockford suggests you avoid. By understanding them you can make proper use of them and avoid the pitfalls.
The "Up & Going" book includes a section on Equality, with this specific summary of when to use the loose (==) vs strict (===) operators:
To boil down a whole lot of details to a few simple takeaways, and help you know whether to use == or === in various situations, here are my simple rules:
If either value (aka side) in a comparison could be the true or false value, avoid == and use ===.
If either value in a comparison could be of these specific values (0, "", or [] -- empty array), avoid == and use ===.
In all other cases, you're safe to use ==. Not only is it safe, but in many cases it simplifies your code in a way that improves readability.
I still recommend Crockford's talk for developers who don't want to invest the time to really understand Javascript—it's good advice for a developer who only occasionally works in Javascript.
If you know they are strings, then there's no need to check for type.
"a" == "b"
However, note that string objects will not be equal.
new String("a") == new String("a")
will return false.
Call the valueOf() method to convert it to a primitive for String objects,
new String("a").valueOf() == new String("a").valueOf()
will return true
Just one addition to answers: If all these methods return false, even if strings seem to be equal, it is possible that there is a whitespace to the left and or right of one string. So, just put a .trim() at the end of strings before comparing:
if(s1.trim() === s2.trim())
{
// your code
}
I have lost hours trying to figure out what is wrong.
Hope this will help to someone!
You can use == or === but last one works in more simple way (src)
a == b (and its negation !=)
a === b (and its negation !==)
what led me to this question is the padding and white-spaces
check my case
if (title === "LastName")
doSomething();
and title was " LastName"
so maybe you have to use trim function like this
var title = $(this).text().trim();
There are actually two ways in which strings can be made in javascript.
var str = 'Javascript'; This creates a primitive string value.
var obj = new String('Javascript'); This creates a wrapper object
of type String.
typeof str // string
typeof obj // object
So the best way to check for equality is using the === operator because it checks value as well as type of both operands.
If you want to check for equality between two objects then using String.prototype.valueOf is the correct way.
new String('javascript').valueOf() == new String('javascript').valueOf()
String Objects can be checked using JSON.stringify() trick.
var me = new String("me");
var you = new String("me");
var isEquel = JSON.stringify(me) === JSON.stringify(you);
console.log(isEquel);
Strict Comparisons
To do simple comparison, use === to check for strict equality. As others stated, this has the advantages of being most efficient and reducing the chances of buggy or uncertain code. Source: MDN Web Docs: Strict Equality.
var a = "hello1";
var b = "hello2";
console.log("a === a?" + (a === a) + "|");
console.log("a === b?" + (a === b) + "|");
Alphabetical Comparisons
If you want to compare two strings to know if a string comes before or after another string, based on natural sorting, use the <, >, <=, and >= operators. Source: MDN WebDocs for <, >, <=, and >=.
var a = "hello1";
var b = "hello2";
console.log("a < a?" + (a < a) + "|");
console.log("a < b?" + (a < b) + "|");
console.log("a > b?" + (a > b) + "|");
console.log("b > a?" + (b > a) + "|");
Considering that both strings may be very large, there are 2 main approaches bitwise search and localeCompare
I recommed this function
function compareLargeStrings(a,b){
if (a.length !== b.length) {
return false;
}
return a.localeCompare(b) === 0;
}
For strings, we have a supported method localCompare which is very handy in string comparison. IMO, we should just use it and doesn't need to complicate stuff.
Usage:
const a = 'Hello'
const b = 'Hell'
a.localCompare(a) // 0
a.localCompare(b) // 1
b.localCompare(a) // -1
Also consider that ["foo", "bar"] == "foo,bar".