相等,还是不等(4)
入门。
在连续对多个相等条件进行判断的时候,可以用and
(&&
),or
(||
)来连接,但并不是所有的条件都会被检查,比如&&在遇到第一个False
的时候,无论后面的真假,可以直接返回False
;同样的||
在遇到第一个True
的时候整个语句的真假已定。
放弃?
这个坑源自这篇文章:什么时候a==1 && a==2 && a==3
?
var aᅠ = 1;
var a = 2;
var ᅠa = 3;
if (aᅠ == 1 && a == 2 && ᅠa == 3) {
console.log('Whaaaaa?');
}
进阶!
方法 1
谜底揭开的时候,我的第一感觉是,这好无聊...实际上三个a
并不是同一个变量,这里用到了一个不可见的韩语的 Unicode 字符U+FFA0
,叫做 Halfwidth Hangul Filler,第一个变量是a
后面加上那个字符,而第三个是a
之前加上那个字符,由于不可见,所以看起来好像是同一个a
。可以把它转换为十六进制看看:
> "ᅠa".charCodeAt(0).toString(16)
'ffa0'
正是U+FFA0
。
方法 2
另一种方法满足a==1 && a==2 && a==3
而不需要不可见字符:
let n = 1;
let a = {valueOf() {return n++;}}
console.log(a == 1 && a == 2 && a == 3) // => true
在 JavaScript 中,任何一个 object 都有valueOf()
这个方法(类似于toString()
),这个 object 在计算中会用valueOf()
来产生一个值:
> b = {valueOf: () => 10}
{ valueOf: [Function: valueOf] }
直接打印出 b 并不会看到 10:
> b
{ valueOf: [Function: valueOf] }
但放在计算中则会现原形:
> b == 10
true
> b == 1
false
> b + 20
30
方法 3
方法 2 如果用===
则返回的是false
:
console.log(a === 1 && a === 2 && a === 3); // => false
因为虽然计算 b 的值的时候返回的是 10,它的类型依然是 object:
> typeof(b)
'object'
这是一种满足===
的方法:
let i = 0;
Object.defineProperty(global, 'a', {
get: function () {
return ++i;
},
});
console.log(a === 1 && a === 2 && a === 3); // => true
如果不是在 node 而是在浏览器中运行需要将global
换成window
。这两个特殊的全局 object 的 property 可以直接使用。而且作为 property,a
的类型跟它的返回值相同为number
> typeof(a)
'number'