I'd like to know whether String.replace() actually found a match and performed a substitution. Since String.replace() returns the resulting string rather than the number of substitutions performed, it seems that I would have to compare the original with the result.
The question is, should I use === or == for that comparison?
As far as I can tell, neither the Mozilla documentation nor the ECMAScript 5.1 Standard specifies that the string that is returned must be the same object as the string that was passed in, if no match occurred.
On the other hand, it would seem stupid for any implementation of JavaScript to return a copy of an unchanged string.
In concrete terms, what happens with
var s = 'abc';
var t = s.replace(/d/, 'D');
console.log(s === t); // I expect true, but am not sure
Is it
Guaranteed to print true? If so, where is that behaviour documented?
Undefined and unreliable behaviour (i.e., I should test s == t instead, or do something clever with a replacement callback closure)?
Undefined behaviour that in practice returns true on every JavaScript implementation?
Edit
#cookiemonster asks:
So it seems that you're not really wondering if the result is guaranteed, but more whether an implementation is optimized to perform an identity comparison internally. Is that right?
Actually, I did screw up the question, and it ended up being an X-Y problem. What I really want to know is, how can I check whether any substitution occurred (the actual number of substitutions doesn't matter — one or more times are all the same)? And do so efficiently, without doing a separate .match() or a character-by-character comparison. And be certain that the result is guaranteed by the language specification.
=== won't work with a String object:
a = new String("foo")
a.replace(/XXX/, "") == a
> true
a.replace(/XXX/, "") === a
> false
or any object that has a custom toString method:
b = { toString: function() { return "foo" }}
"foo".replace(/XXX/, "") == b
> true
"foo".replace(/XXX/, "") === b
> false
Most of the time, this is a non-issue, but "praemonitus, praemunitus" as they say.
To answer your update: as seen here, at least V8 is optimized to return the subject itself if no replacements can be made:
int32_t* current_match = global_cache.FetchNext();
if (current_match == NULL) {
if (global_cache.HasException()) return isolate->heap()->exception();
return *subject; <-------
and, although the standard only requires two strings to look the same to be strict equal (===), I'm absolutely positive that every JS engine out there is smart enough to avoid strcmp on equal pointers.
It makes no difference.
Why? Because String.replace operates on strings, and returns a string. Also, strings are primitives, not objects.
You already know that you have two strings. == and === are therefore identical for this purpose. I'd even go so far as to say that === is superfluous.
The replace method on the String class always returns a string, so === is just as safe to use and reliable as == since no type coercion will happen. Secondly, if no substitution occurred, the === test will return true since they contain the same characters.
Given your example...
"Is it Guaranteed to print true? If so, where is that behaviour documented?"
Yes, it is. It's documented in the respective equality comparison algorithms used by == and ===.
Abstract Equality Comparison Algorithm
Strict Equality Comparison Algorithm
"Is it Undefined and unreliable behaviour (i.e., I should test s == t instead, or do something clever with a replacement callback closure)?"
No, it's well defined behavior. See above. The == and === operators will behave identically.
"Is it Undefined behaviour that in practice returns true on every JavaScript implementation?"
As long an implementation is following the specification, it will return true.
Related
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.
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
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
As a follow-up to this question: Is there ever a reason to write "if (myBoolean == true)" in a JavaScript conditional? -
Why is it good practice to use if (myBoolean === true) in JavaScript? As a relatively inexperienced JavaScript user, I'm trying to work out in what specific, real-world scenarios you'd end up with a value that might be a Boolean true or might be a "truthy" value, so that you would need to check if (myBoolean === true) rather than if (myBoolean)
I'll challenge the premise of the question: I don't think it's good practice, nor do I think there's a general consensus that it is. :-)
The only reason for using === true would be if you weren't sure that myBoolean was actually a boolean and you wanted the result to be false if it weren't. There are use cases for that, but they're quite limited. 99.9% of the time, simply if (myBoolean) suffices, even though it will be true for 1, "foo", and other truthy values.
There are times when using strict equality for other reasons is quite a good idea, because JavaScript's rules for loose equality if the operands are of different types are quite complex. But if you're using something as a flag, there's little if any point to using === on it.
One particular place where I've seen === used with boolean values is in code inspired by jQuery, where a callback function can cancel an action by returning false, but doesn't have to return anything. When a function has no explicit return value, the result of calling that function is undefined, which is, of course, falsey. So code that wants to check whether the function returned false, not just undefined, would do this:
if (callback(args) === false) {
// The callback explicitly returned false (not just a falsey value), cancel
// ...
}
But that's a relatively infrequent use case, and of course it involves === false as opposed to === true...
Some random example:
function CreateSomeObject(param)
{
if (param == "1")
{
return new Stuff();
}
return null;
}
var myBoolean = CreateSomeObject("1") || true;
if (myBoolean === true)
{
//doesn't execute
}
if (myBoolean)
{
//executes just fine
}
In case of null only , you want to do that , although I never used this because it feels like more verbose and long string. No problem using it or avoiding it.It is more of style you want to write the code.
I constructed a slightly convoluted answer and then realised that the main reason is in the falsy values rather than the truthy ones. Usually, a function returns one kind of thing, and there is only one falsy value (the empty string for a string function, or 0 for a numeric one, or whatever).
However, when you aren't sure if something is defined or not, it can be instructive:
waitForResponse(request, 5000);
if(!request.ResponseValue) {
alert('Server failed to respond');
}
vs
waitForResponse(request, 5000);
if(request.ResponseValue === 'false') {
alert('Server says no');
}
Although I'd argue that you should check for undefined rather than boolyness:
if(typeof request.ResponseValue === 'undefined') {
//...
}
Incidentally, typeof is fast, at least it was in Chrome last time I checked.
Personally, I don't like statements like it's good practice to x. IMO, it all depends on the context: if you want to check some object exists, if(objectX) will do just as if (objectX === undefined) or if (typeof objectX === 'undefined') and even if (typeof objectX == 'undefined').
The reason why some people, like Douglas Crockford, strongly advocate the use of value and type checking (===) is that falsy and truthy values can, in rare cases, produce unexpected results:
var falsy = '';
if (falsy)
{//only when falsy is truthy, but an empty string is falsy
console.log('could be seen as counter-intuitive: var was declared and assigned an empty string, but is falsy');
}
var obj = {falsy:''}
if (!obj.falsy)
{
console.log('I might assume falsy is not set, although it was:');
console.log(obj.hasOwnProperty('falsy'));//true
}
Again, this might just be my opinion, but in the vast majority of cases this won't break your code. I'd even go one step further: Douglas Crockford might claim that using checking for falsy values isn't a good idea, but he does like the logical OR (||) operator:
var falsy ='';
var someVar = falsy || 'default value';//this relies heavily on falsy values
The only "solid" arguments for strict comparison are:
if you need the variable to be a boolean, but then again falsy = !!falsy; coerces to a boolean all the same
strict comparisons are marginally faster, but you'll have to do a whole lot of comparisons before you'll be able to notice the difference
Having said that, I do tend to use strict comparisons an awful lot, again, it might be a personal thing, but I like to know what the actual type of a variable is:Given that '1' == 1 evaluates to true, but '1' === 1 is false, it at least allows you to coerce a var to the type you need:
var foo = '00001';
var elements = [foo = ('00000' + (+(foo)+1)).substr(-5)];
while(elements[+(foo)-1])
{
foo = ('00000' + (+(foo)+1)).substr(-5);
elements.push(foo = ('00000' + (+(foo)+1)).substr(-5));
}
Now this isn't what you'd call good code, but there's a lot of type-juggling going on. At the end of the ride, you might want to know what value was assigned to foo. That's not an issue in this snippet, but suppose you want to use the numeric value of foo inside the while loop, if it's an odd number:
var foo = '00001';
var elements = [foo = ('00000' + (+(foo)+1)).substr(-5)];
while(elements[+(foo)-1])
{
foo = ('00000' + (+(foo)+1)).substr(-5);
elements.push(foo = ('00000' + (+(foo)+1)).substr(-5));
if (+(foo)%2 === 1)
{
foo = +(foo);
//do stuff with foo
}
}
The easiest way to check weather or not foo is a string after the loop is completed is to check foo directly: if (foo === +(foo))
I am well aware that this example is a little far-fetched, but I have encountered a case quite similar to this one. It's at times like this where the advantages of strong-typed languages really show. speaking of which: new Date() >= someDateObject vs Date() >= someDateObject... try it in your console and you'll soon see what I'm on about.
While it's clear how using the === operator for e.g. numbers is useful (0, null and undefined all being falsy values, which can lead to confusion), I'm not sure if there are benefits to using === for string comparisons.
Some of my team mates use this operator for all comparisons, but does it really make sense? Is there at least some minor performance impact?
If you know the types are the same, then there's no difference in the algorithm between == and ===.
That said, when I see ==, I assume that I'm using it for its type coercion, which makes me stop and analyze the code.
When I see === I know that there's no coercion intended, so I don't need to give it a second thought.
In other words, I only use == if I intend for there to be some sort of type coercion.
It is considered good practice to always use === for comparisons in JavaScript. Since JavaScript is a dynamic language, it is possible that what you think are two strings could be variables with different types.
Consider the following:
var a = "2", b = 2;
a == b // true
a === b // false
The only way to guarantee a false result in this case would be to use === when comparing the two values.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Javascript === vs == : Does it matter which “equal” operator I use?
In Douglas Crockford's book Javascript: The Good Parts, it is recommended to not use == at all, due to hard to memorized rules. Do advanced or seasoned Javascript programmers really not use == or !=?
If so, then I guess we will be using === and !==, but then how do we use them effectively? Is the most common case comparing a string with number, so we can always do
if (Number(s) == 3) { ... } // s is a string
Can Number(s) work in most browsers? And what are the other common cases to use with ===?
The problem with == is that it uses type-coercion which can have unexpected results.
You nearly always want === or !==. You can explicitly change the types as appropriate. In your example it would be easier to write "3" as a string instead of converting the string to a number.
Never say never, but indeed, in most cases it is best to use the more strict === and !== operators, because they compare the value as well as the type.
Comparing '68' to 68 is not a problem, if it matches, it is probably what you meant. The big risk in not doing so lies especially in 'empty values'. Empty strings may be evaluated as false, as may 0 and 0.0. To prevent hard to find errors, it is best to do a strict type comparison as well.
If you want something to be true or false, it should be true or false and not any other value. Even in cases where these other types would be allowed, it may be better to explicitly convert it to the type you're comparing with, just for the sake of readability, maintanability and clarity. You are in that case making clear that you know the value can be of another type and that it is allowed so. With just using the less strict operator, no one can tell if you just forgot or made a deliberate choice.
So yes, I'd say it's a best practise to always use the strict operators, although there will always be exceptions.
=== is 'exactly equal to' where == is not exact.
For example,
'' == false // true
0 == false // true
false == false // true
'' === false // false
0 === false // false
false === false // true
== will return true for 'falsy' or 'truthy' values. Read this for more information.
A lot of developers will use ===. It does not hurt to use === solely. But in some cases === is not necessary. Crockford suggests a lot of things in his book. Some people follow his word to the T. Others, myself included, take it all with a grain of salt. He has some good points, but a lot of it is preference.
You should make sure you know exactly what == and === do. And with that information you can decide how to use them, and when.
== operator compares two operands values and returns a Boolean value.
=== This is the strict equal operator and only returns true if both the operands are equal and of the same type.
Example:
(2 == '2') //return true
(2 === '2') //return false