懵逼的判断a==1 && a==2 && a==3

遇到一个懵逼的判断

if( a == 1 && a == 2 && a == 3 ) {
  console.log(1);
}

咋一眼看上去,是不是觉着这是哪个傻逼写出来的,这不是永远不会成立的代码嘛…这就是我第一眼的感觉,疯了,但是它又是出自不可能出错的地方,那咋办,找问题呗…
在这里,其实有个误区,就是a的值,它不是同一时间为1、2、3的,它要有个运算,先来一个a1运算,再来一个a2运算,最后才到a==3运算,现在这么说是不是也有点懵逼呢,下来我详细说
在这里,我们看a的值哈,它就不可能是一个基础类型的值,因为基础类型的值即便是Number转换后与后面值比较,它也是永远不会变的啊,都是这个a的值必须是一个对象,前面有文中写比较运算符对象和数值做比较的时候,我也曾说过对象有个属性valueOf方法,当时我还挺懵逼对象和一个数值做比较,为啥啊,对象的valueof执行后就是对象自己啊,还要和一个值做比较,傻逼嘛,会一直是false的…现在想来,是我们己傻逼,人家这么弄必然有这么比较的原因啊…
先来看看这个valueof方法

let obj = {i:0}.  //先来定义一个对象,并且有一个i:0的属性

然后,我们访问他的原型,

obj.__proto__.valueOf  // ƒ valueOf() { [native code] }

可以看到是有一个valueOf的方法的,这个就是上面说的谁调用返回谁的那个方法啦
然后我们现在对比obj和数值吧,

obj ==1   // false

结果可想而知,肯定是false啊,这里有个默认转哈,就是对象和值做比较的时候会默认调用valueOf方法,代码上看不到,但是不代表它没有默默的在执行哈
其实它对比的时候会变成这个样子

obj.valueOf() == 1. //false

呃,是不是有点感觉了,默认情况下,valueOf是原生对象中的啊,那如果我们自己写一个valueOf呢,那执行的时候不就调用自己写的valueOf了嘛,我们让它返回啥它就返回啥,是不是这个意思,来看看吧

obj.valueOf = function(){   // 自己写一个valueOf方法,返回一个数值1
    return 1;
}

此时,我们再来和1比较一下

obj == 1。// true

哎呦,和我们预期的一样,返回的值和右边的值做比较,返回true了,哈哈哈

那我们再回头看最初的判断哈 a1 && a2 && a==3
啥时候会为真呢,这里每一次比较都调用一次valueOf方法,那我们每次让它加1不就行了嘛,对吧,改造一下valueOf吧

obj.valueOf = function(){
    this.i++;  // 每次调用都自增1
    return this.i;
}

打印obj来看看

{
	i: 0,
	valueOf(){
		this.i++;  
    	return this.i;
	}
}

我们依次执行

obj == 1 // true
obj == 2 // true
obj == 3 // true

是不是一下就明白了,很哇塞吧

再来写一遍代码,巩固一下

let a = {i:0}
a.valueOf = function(){
    this.i++;
    return this.i;
}
if(a==1 && a==2 && a==3){
    console.log("success")
}

打印success了,哈哈哈,问题解决!

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值