我正在检查JS规范,并遇到了这种奇怪的行为:
假设你想要一个数字代表你拥有的动物,以节省记忆。
将该数字转换为二进制值,您必须将其拆分为一个数组并且每次都pop
,因为您没有领先0
&#39 ; S
好的,听起来很模糊,所以让我们举个例子:
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表现得这么奇怪吗?
答案 0 :(得分:7)
JavaScript:0在某些情况下代表是真的吗?
不,值0
绝不是真的。值"0"
是真实的(包含数字0
的字符串),但值0
不是。 "0"
(字符串)是真实的这一事实是您第一个示例的行为方式。
如果您希望循环显示您期望的结果,请将字符串强制转换为数字:
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());

答案 1 :(得分:4)
这是因为你的案例中的'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'.
答案 2 :(得分:1)
您的数组包含" 0"和" 1" 。字符串" 0"或" 1"是真的