JavaScript: 0在某些情况下代表true

JavaScript: 0 represents true in some cases?

本文关键字:情况下 true JavaScript      更新时间:2023-09-26

我正在检查JS规范,并遇到了这个奇怪的行为:

  • 假设你有一组动物。
  • 假设你想用一个数字来代表你拥有的动物,以节省内存。

    • 该数字实际上代表了数字的二进制值,可以用来转换为布尔值数组。
  • 将该数字转换为二进制值,您必须将其拆分为一个数组,并且每次都要将该值拆分为pop,因为您没有领先的0

好吧,这听起来很模糊,所以让我们举个例子:

var pets = ['cat', 'dog', 'salamander', 'fish', 'lion', 'ape'];
var iHavePets = parseInt(1001, 2); // 9
// we can't have leading 0's, so read this right to left.
// this actually represents 001001
var petBools = iHavePets.toString(2).split("");
console.log(petBools);
while(pets.length > 0){
   // petBools == [1, 0, 0, 1]
   // popping it would represent: 1, 0, 0, 1, undefined, undefined
    console.log(petBools.pop() ? !!pets.pop() : !pets.pop());
}
// remember we pop(), so read right to left in the array's.
// here I expect the following:
// We start with a 1
// so pets.pop() should push true
// then we have a 0
// so !pets.pop() should push false.
// however: the 0 is actually true in this case, causing it to push 'true'.

同样的手工示例也可以:

var fish = ['salmon', 'tuna', 'shark'];
console.log(1 ? !!fish.pop() : !fish.pop()); // true
console.log(0 ? !!fish.pop() : !fish.pop()); // false
console.log(undefined ? !!fish.pop() : !fish.pop()); // false

谁能给我解释一下为什么JS的行为如此奇怪?

JavaScript: 0在某些情况下代表true ?

不,0值永远不为真。"0"为真值(字符串包含数字0), 0不为真值。事实上,"0" (字符串)是真实的,这就是为什么你的第一个例子的行为方式。

如果你想让你的循环显示你期望的结果,强制字符串为number:

console.log(+petBools.pop() ? !!pets.pop() : !pets.pop());
// ---------^

或转换而不是强制(只是稍微改变规则,"0""1"没有区别):

console.log(parseInt(petBools.pop()) ? !!pets.pop() : !pets.pop());
// ---------^^^^^^^^

为什么JS的行为如此奇怪?

因为pop突变操作。如果您对所有操作使用相同的数组,您将得到一致的结果:

var fish;
fish = ['salmon', 'tuna', 'shark'];
console.log(1 ? !!fish.pop() : !fish.pop());
fish = ['salmon', 'tuna', 'shark'];
console.log(0 ? !!fish.pop() : !fish.pop());
fish = ['salmon', 'tuna', 'shark'];
console.log(undefined ? !!fish.pop() : !fish.pop());

这是因为'0'在您的情况下是字符串 0而不是数字0

如果您将0更改为0,您将获得false的预期行为

    var pets = ['cat', 'dog', 'salamander', 'fish', 'lion', 'ape'];
    var iHavePets = parseInt(1001, 2);
    // we can't have leading 0's, so read this right to left.
    // this actually represents 001001
    var petBools = iHavePets.toString(2).split("");
    console.log(petBools);
    while(pets.length > 0){
      // petBools == [1, 0, 0, 1]
      //console.log(petBools);
      var poppedValue = parseInt(petBools.pop(), 10)
      // popping it would represent: 1, 0, 0, 1, undefined, undefined
      console.log(poppedValue ? !!pets.pop() : !pets.pop());
    }
    // remember we pop(), so read right to left in the array's.
    // here I expect the following:
    // We start with a 1
    // so pets.pop() should push true
    // then we have a 0
    // so !pets.pop() should push false.
    // however: the 0 is actually true in this case, causing it to push 'true'.

您的数组包含字符串"0"answers"1",字符串"0"或"1"为真