I’ve heard of boolean arithmetic and thought of giving it a try.
alert (true+true===2) //true
alert (true-true===0) //true
So algebra tells me true=1
alert (true===1) //false :O
Could someone explain why this happens?
=== is the strict equality operator. Try == operator instead.
true==1 will evaluate to true.
The strict equality operator === only considers values equal if they
have the same type. The lenient equality operator == tries to
convert values of different types, before comparing like strict
equality.
Case 1:
In case of true===1, The data type of true is boolean whereas the type of 1 is number. Thus the expression true===1 will evaluate to false.
Case 2:
In case of true+true===2 and true-true===0 the arithmetic operation is performed first(Since + operator takes precedence over ===. See Operator Precedence) and then the result is compared with the other operand.
While evaluating expression (true+true===2), the arithmetic operation true+true performed first producing result 2. Then the result is compered with the other operand. i.e. (2==2) will evaluate to true.
Because comparing data TYPE and value (that's what operator '===' does ), TRUE is not exactly the same as 1. If you changed this to TRUE == 1, it should work fine.
At the beginning, you're doing bool + bool. The + operator takes precedence over the === operator so it's evaluated first. In this evaluation, it's converting the booleans to their number forms. Run console.log(true + true); and this will return 2. Since you're comparing the number 2 to the number 2, you get a return value true with the strict equality.
When you're just comparing true === 1, like everyone else said you're comparing the boolean true to the number 1 which is not strictly equal.
first 2 expression are true because you are using expression (true+true) (true-true) it convert type of a value first due to expression and check equality with "===", toNumber and toPrimitive are internal methods which convert their arguments (during expression ) this is how conversion take place during expression
That's why true+true equal to the 2
In your third expression you are using === this not convert arguments just check equality with type, to make it true both values and there type must be same.
Thats all
Related
I was perusing the underscore.js library and I found something I haven't come across before:
if (obj.length === +obj.length) { ... }
What is that + operator doing there? For context, here is a direct link to that part of the file.
The unary + operator can be used to convert a value to a number in JavaScript. Underscore appears to be testing that the .length property is a number, otherwise it won't be equal to itself-converted-to-a-number.
According to MDN:
The unary plus operator precedes its operand and evaluates to its
operand but attempts to converts it into a number, if it isn't
already. For example, y = +x takes the value of x and assigns that to
y; that is, if x were 3, y would get the value 3 and x would retain
the value 3; but if x were the string "3", y would also get the value
3. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a
number, because it does not perform any other operations on the
number. It can convert string representations of integers and floats,
as well as the non-string values true, false, and null. Integers in
both decimal and hexadecimal ("0x"-prefixed) formats are supported.
Negative numbers are supported (though not for hex). If it cannot
parse a particular value, it will evaluate to NaN.
It's a way of ensuring that obj.length is a number rather than a potential string. The reason for this is that the === will fail if the length (for whatever reason) is a string variable, e.g. "3".
It's a nice hack to check whether obj.length is of the type number or not. You see, the + operator can be used for string coercion. For example:
alert(+ "3" + 7); // alerts 10
This is possible because the + operator coerces the string "3" to the number 3. Hence the result is 10 and not "37".
In addition, JavaScript has two types of equality and inequality operators:
Strict equality and inequality (e.g. 3 === "3" expresses false).
Normal equality and inequality (e.g. 3 == "3" expresses true).
Strict equality and inequality doesn't coerce the value. Hence the number 3 is not equal to the string "3". Normal equality and inequality does coerce the value. Hence the number 3 is equal to the string "3".
Now, the above code simply coerces obj.length to a number using the + operator, and strictly checks whether the value before and after the coercion are the same (i.e. obj.length of the type number). It's logically equivalent to the following code (only more succinct):
if (typeof obj.length === "number") {
// code
}
The same goes for '1\t' (and probably others).
if (1 == '1\n') {
console.log('Equal');
}
else {
console.log('Not Equal');
}
As said before if you compare number == string, it will automatically try to convert the string to a number. the \n and \t are simply whitespace characters and therefore ignored.
This and similar behaviour can be rather confusing leading to situations like this:
(Picture taken from: https://www.reddit.com/r/ProgrammerHumor/comments/3imr8q/javascript/)
The equality operator(==) converts the operands if they are not of the same type, then applies strict comparison. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
1 is of type Number hence '1\n' is converted to Number first then comparison takes place!
And Number() constructor will convert the string('1\n') to 1 :-
Number('1\n') === 1
In Strict equality using ===, Neither value is implicitly converted to some other value before being compared. If the values have different types, the values are considered unequal.
Hence 1 === '1\n' will be expressed as false
I found these examples in another thread but I don't get it.
0 == '0' // true
0 to the left I converted to false(the only number that does that). The right is a non empty string which converts to true.
So how can
false == true --> true
What have I missed?
Here is an official answer to your question (the quoted parts, link at the bottom) and analysis:
Equality (==)
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the string operand is converted to a number if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
Syntax
x == y
Examples
3 == 3 // true
"3" == 3 // true
3 == '3' // true
This means, as I read it, that the first 3 (integer) is converted to string to satisfy the comparison, so it becomes '3' == '3', which is true, same as in your case with zeroes.
NOTE: I assume that the converion may vary in different JS engines, although they have to be unified under ECMAScript specifiction - http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3 (quoted #Derek朕會功夫). This assumption is made on a subjective and imperative opinion that not all browsers and JavaScript engines out there are ECMAScript compliant.
Identity / strict equality (===)
The identity operator returns true if the operands are strictly equal (see above) with no type conversion.
The Identity / strict equality (===) found on the same resource at the end of the answer will skip the automatic type conversion (as written above) and will perform type checking as well, to ensure that we have exact match, i.e. the expression above will fail on something like:
typeof(int) == typeof(string)
This is common operator in most languages with weak typing:
http://en.wikipedia.org/wiki/Strong_and_weak_typing
I would say that one should be certain what a function/method will return, if such function/method is about to return numbers (integers/floating point numbers) it should stick to that to the very end, otherwise opposite practices may cut your head off by many reasons and one lays in this question as well.
The above is valid for other languages with weak typing, too, like PHP for example.
Read more of this, refer second head (Equality operators):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators
When you use == JavaScript will try very hard to convert the two things you are trying to compare to the same type. In this case 0 is converted to '0' to do the comparison, which then results in true.
You can use ===, which will not do any type coercion and is best practice, to get the desired result.
Equality operator
The equality operator converts the operands if they are not of the same type, then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the string operand is converted to a number if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators
JavaScirpt Table Equality: http://dorey.github.io/JavaScript-Equality-Table/
I always thought that JavaScript's if statements did some kind of casting magic to their arguments, but I'm a little wary of what's actually going on behind the scenes.
I recently found a JavaScript comparison table and noticed that even though -1 == true evaluates to false, if(-1){...} will execute.
So within JavaScripts if statements, what happens to the expression? It seems reasonable to assume that it uses !!{expression} to cast it to an inverse boolean, then invert it again, but if that's the case, how does JS decide whether an object's inverse boolean representation is truthy or not?
JavaScript is wonky.
Yes, -1 == true results in false, but that's not what the if statement is doing. It's checking to see if the statement is 'truthy', or converts to true. In JavaScript, that's the equivalent of !!-1, which does result in true (all numbers other than zero are truthy).
Why?!?
The spec defines the double equals operator to do the following when presented with a number and a boolean:
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
ToNumber will convert the boolean true into the number 1, so you're comparing:
-1 == 1
which anyone can tell you is clearly false.
On the other hand, an if statement is calling ToBoolean, which considers any non-zero, non-NaN number to be true.
Any JavaScript developer really needs to look at the documentation -- for this case, located here: http://www.ecma-international.org/ecma-262/5.1/#sec-9.2
9.2 ToBoolean
The abstract operation ToBoolean converts its argument to a value of type Boolean according to Table 11:
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
(Sorry about the formatting, can't make a table here.)
From JavaScript The Definitive Guide
The following values convert to, and therefore work like, false:
undefined
null
0
-0
NaN
"" // the empty string
All other values, including all objects (and arrays) convert to, and work like, true. false, and the six values that convert to it, are sometimes called falsy values, and all other values are called truthy.
These things by themselves are falsy (or evaluate to false):
undefined
null
0
'' or ""
false
NaN
Everything else i truthy.
Truthy-ness or falsy-ness is used when evaluating a condition where the outcome is expected to be either truthy (true) or falsy (false).
In your example if(-1 == true), you are comparing apples and oranges. The compare is evaluated first (and resulted in false), and the results of that is used in your condition. The concept of truthyness/falsyness isn't applied to the operands the comparison.
When if state using with comparing variable different type js use .toString и .valueOf ( for more information check http://javascript.info/tutorial/object-conversion ) - just keep this in mind - it make so example much more easy to understand
Is it true that in if-statement JavaScript wrap the condition into a Boolean?
if(x) => if(Boolean(x))
Is it true that in comparison JavaScript wrap the compare elements into a Number?
a == b => Number(a) == Number(b)
Yes, and No.
For the first part, yes, that is essentially what the javascript does.
But for the latter, no. Not everything in JavaScript can be converted to a number. For example:
Number('abc') // => NaN
And Not-A-Numbers are not equal:
NaN == NaN // => false
So something like this:
Number('abc') == Number('abc') // => false!
But that's actually true with equality comparison.
'abc' == 'abc' // => true
As a side note, it's probably better to use === in JavaScript, which also checks the type of the values being compared:
0 == '0' // => true
0 === '0' // => false, because integer is not a string
More details about === can be read over here.
Yes, that's true, x is evaluated in a boolean context in this situation, so the equivalent of Boolean(x) is applied.
No, that's not true. It only looks that way because the coercitive equality operator == tries to convert a and b to the same type. Number() is only applied if either a or b is already a Number. For instance:
>>> 0x2A == 42
true // both 'a' and 'b' are numbers.
>>> "0x2A" == 42
true // 'a' is a string whose number coercion is equal to 'b'.
>>> "0x2A" == "42"
false // 'a' and 'b' are different strings.
Is it true that in if-statement JavaScript wrap the condition into a Boolean?
Usually yes.
Is it true that in comparison JavaScript wrap the compare elements into a Number?
Absolutely no.
Explanation
From JavaScript Language Specifications.
The if statement is defined at § 12.5 as:
if ( Expression ) Statement else Statement
It says that the Expression will be evaluated, converted with GetValue() and then tested after the ToBoolean() conversion.
Then the first assertion is true (but see later), the condition for the if statement is evaluated like is passed as parameter to the Boolean function. Please recall how JavaScript handles type conversion to boolean (§ 9.2):
undefined and null values are converted to false.
numbers are converted to false if ±0 or NaN otherwise they're converted to true.
strings are converted to false if empty otherwise always to true regardless their content.
objects are always converted to true.
Because of the call to GetValue() strictly speaking this assertion is not always true, take a look to § 8.7.1 where the standard describes how GetValue() works, here can happen some magic conversion before ToBoolean() is called.
The == operator is defined as in § 11.9.3.
As you can see it doesn't specify that operands must be (or will be treated as) numbers, the behavior of the operator is different and regulated by a series of rules based on the type of the operands. Then your second assertion is false. The case they're numbers (or one of them is a number) is just a special case in the algorithm, please note that at point 4 of the algorithm it says that if one of them is a number and the other one is a string then it'll be converted with ToNumber(), only in this case (with all the implications that this conversion has).
It's intuitive if you think that you can compare functions, strings or numbers, not every type can be converted to a numeric value.