admin管理员组文章数量:1278823
I have the following code snippet:
if([]) {
console.log("first is true");
}
The console
says first is true
which means []
is true. Now I am wondering why this:
if([] == true) {
console.log("second is true");
}
and this:
if([] === true) {
console.log("third is true");
}
are not true
. If the console logged first is true
in the first snippet, that means []
should be true, right? So why do the latter two parisons fail? Here is the fiddle.
I have the following code snippet:
if([]) {
console.log("first is true");
}
The console
says first is true
which means []
is true. Now I am wondering why this:
if([] == true) {
console.log("second is true");
}
and this:
if([] === true) {
console.log("third is true");
}
are not true
. If the console logged first is true
in the first snippet, that means []
should be true, right? So why do the latter two parisons fail? Here is the fiddle.
- 1 Understanding javascript truthy and falsy – Hugues M. Commented Jun 14, 2017 at 16:28
- You cant test an array for truthiness. Are you trying to test if it exists? – Korgrue Commented Jun 14, 2017 at 16:30
4 Answers
Reset to default 11This is by specification. By the ECMAScript 2015 Language Specification, any object that is implicitly coerced into a boolean is true; that means objects are truthy. Inside of an if
statement, the condition, once evaluated and if not already boolean, is coerced into a boolean. Thus, doing:
if([]) {
...
}
[]
is truthy when coerced to a boolean and is true.
On the other hand, when you try to pare two values of differing types with abstract parison, ==
, the engine must internally go through an algorithm to reduce the values to similar types, and ultimately integers that it can pare. In Section 7.2.12 of the specification on the steps for Abstract Equality Comparison x == y
, it states:
7.2.12 Abstract Equality Comparison
The parison x == y, where x and y are values, produces true or false. Such a parison is performed as follows:
[...]
- If Type(y) is Boolean, return the result of the parison x == ToNumber(y).
Thus, the y
operand (in this case true
) is converted to 1 by coercion with ToNumber
since it is a boolean, and [] == 1
is false because:
- If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the parison ToPrimitive(x) == y.
This will convert the x
operand to a string with the toString
method of the array, which is ""
for an empty array in this case. After going through ToPrimitive
, it will result in:
if("" == 1) {
...
}
And finally:
- If Type(x) is String and Type(y) is Number, return the result of the parison ToNumber(x) == y.
Thus, ToNumber
of an empty string ""
is 0 and you get:
if(0 == 1) {
...
}
And 0 does not equal 1, thus it is false. Remember that just because something is truthy, does not make it equal to true. Just try Symbol() == true
or ({}) == true
.
The final parison, with ===
is strict parison, and does not coerce any operands and will return false if both operands are not the same type. Since the left operand is an object (an array) and the right is a number, the parison evaluates to false.
You have force type coercion before making a Boolean equity check with the Object types.
while "" == false // <- true
or 0 == false // <- true
works out well
with the Object types it doesn't
null == false // <- false
so you better do like
!!null === false // <- true
or !![] === true // <- true
This is strict equality. It meas that both operands should be the same thing. In the case of object, they should be exactly the same object. Comparison between object with the same structure and the same values will fail, they need to be reference to the same object to success.
if([]===true){
console.log("third is true");
}
In case of operands of different types, than the parison between them bees strict. This leads to the case above.
if([]==true){
console.log("second is true");
}
Also, in the first if
statement, []
is automatically casted to boolean true.
Boolean([])
is trying to ascertain whether the operand is truthy or not. Similarly, if([]) console.log('truthy')
is checking whether the expression is truthy or not.
However, true == []
does not immediately decide to check truthiness. Instead, it follows the ==
weak equality checking rules.
The rule for true == []
is:
If one of the operands is an object and the other is a primitive, convert the object to a primitive.
Objects (including arrays) are converted into primitives by calling the @@toPrimitive
method on the object. This method does not exist on regular arrays and objects, but will exist if you add it to an object or declare it as a method of the class of an object.
During the weak equality type coercion, the hint sent to the @@toPrimitive
method is 'default'. However, in other situations, a different hint is provided, allowing the object to coerce to different primitives in different situations.
const a = []
const b = []
b[Symbol.toPrimitive] = function (hint) {
if(hint==='number') return 3;
if(hint==='string') return 'hello'
else return false; // happens when hint is 'default'
}
const log = x=>console.log(x)
log(a==true) // false - a has no toPrimitive function
log(a==false) // false - a has no toPrimitive function
log(b==true) // false - toPrimitive returns false
log(b==false) // true - toPrimitive returns false
log(!b) // false - checks for truthiness, and objects are truthy
log(Boolean(b)) // true - checks for truthiness, and objects are truthy
log(b==3) // false - toPrimitive with hint=default returns false
log(Number(b)) // 3 - toPrimitive with hint=number returns 3
log(b=='hello') // false - toPrimitive with hint=default returns false
log(String(b)) // 'hello' - toPrimitive with hint=string returns 'hello'
log(+b) // 3 - `+` calls toPrimitive with hint=number,
// which returns 3
log(b+"") // 'false' - toPrimitive with hint=default returns false
log(`${b}`) // 'hello' - template literals call toPrimitive with
// hint=string, which returns 'hello'
本文标签: If an array is truthy in JavaScriptwhy doesn39t it equal trueStack Overflow
版权声明:本文标题:If an array is truthy in JavaScript, why doesn't it equal true? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741246110a2364908.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论