资讯专栏INFORMATION COLUMN

JavaScript:(a==1 && a==2 && a==3)能

light / 1656人阅读

摘要:我们举个例子我们可以对上述对象使用方法,他会返回一个对象。在我们的问题中会企图将对象转化成数字的类型,进行比较。幸运的是,在中有符号。当我们每次调用的时候,他会将变量增加返回给我们。

如果你能确切的答出可以,那恭喜你,你可以绕道了
前言

有人会说,这个问题好奇葩,放在别的语言里,这要是能输出true,估计是见鬼了,但是你别说,放在js中好真有可能。最近在一个人的推特上提了一个问题:

问题:Can (a==1 && a==2 && a==3) ever evaluate to true?

答案:yes

在这篇文章中,我将解释这段代码的原理:

const a = {
  num: 0,
  valueOf: function() {
    return this.num += 1
  }
};
const equality = (a==1 && a==2 && a==3);
console.log(equality); // true

你可以打开chorme浏览器,然后打开开发者模式,在console中输入这段代码,你就可以看到输出结果([windows]: Ctrl + Shift + J [mac]: Cmd + Opt + J)

有什么窍门呢?

其实也没有,能有的就是js中的两个概念:

隐式转换

object的valueOf函数

隐式转换

注意:这题里面我们用的是==而不是===,在js中==代表的是等于而不是全等,那么就存在变量的隐式转化问题。这就意味着结果会比我们所期望的更多的可能性。对于js的隐式转化,真的有很多文章,我推荐一下以下几篇博客,如果你想要了解,可以点进去:

推荐博客

valueOf

JavaScript提供了一种将对象转化为原始值的方法:Object.prototype.valueOf(),默认情况下,返回正在被调用的对象。

我们举个例子:

const a = {
  num: 0
}

我们可以对上述对象使用valueOf方法,他会返回一个对象。

a.valueOf();
// {num: 0}

是不是很酷,我们可以用typeOf来检测一下这个输出结果的类型:

typeof a.valueOf();
// "object"

为了让valueOf可以更方便将一个对象转化成原始值,我们可以重写他,换种说法就是我们可以通过valueOf来返回一个字符串、数字、布尔值等来代替一个对象,我们可以看以下代码:

a.valueOf = function() {
  return this.num;
}

我们已经重写了原生的valueOf()方法,当我们调用valueOf的时候,他会返回a.num。那我们现在运行以下:

a.valueOf();
// 0

我们得到0了,这很合理,因为0就是赋给a.num的值。那我们可以来做几个测试:

typeof a.valueOf();
// "number"

a.num == a.valueOf()
// true

很好,但为什么这个很重要呢?

这很重要,因为当你两种不同类型的遇到相等操作符的时候,js会对其进行类型转化——它企图将操作数的类型转化为类似的。

在我们的问题中:(a==1 && a==2 && a==3)JavaScript会企图将对象转化成数字的类型,进行比较。当要转化的是一个Object的时候,JavaScript会调用valueOf()方法。

自从我们改变了valueOf()方法之后,我们能不能做到以下几点呢:

a == 0

// true

我们做到了,异常轻松。

现在我们需要做的的一点是:当我们每次去调用a的值的时候,能改变它。

幸运的是,在JavaScript中有+=符号。

+=这个运算符可以轻松的去改变一个的值,我们可以举个简单的例子:

let b = 1
console.log(b+=1); // 2
console.log(b+=1); // 3
console.log(b+=1); // 4

正如你所见的,我们每次使用加法赋值运算符,可以让我们的变量增加。

所以我们可以将这个观念用到valueOf()中。

a.valueOf = function() {
  return this.num += 1;
}

当我们每次调用valueOf的时候,他会将变量增加1返回给我们。

随着这个改变,我们来运行下面的代码:

const equality = (a==1 && a==2 && a==3);
console.log(equality); // true

这就是它的工作原理。

记住下面两点:

使用相等操作符,js会做强制类型转化

我们的对象每次调用valueOf()它的值会增加1

所以比较的时候我们每次都能得到true。

补充第二点的运算过程

a                     == 1   -> 
a.valueOf()           == 1   -> 
a.num += 1            == 1   -> 
0     += 1            == 1   ->
1                     == 1   -> true
a                     == 2   -> 
a.valueOf()           == 2   -> 
a.num += 1            == 2   -> 
1     += 1            == 2   ->
2                     == 2   -> true
a                     == 3   -> 
a.valueOf()           == 3   -> 
a.num += 1            == 3   -> 
2     += 1            == 3   ->
3                     == 3   -> true
总结

谢谢你观看这个小实验,希望你能从中学到东西,有兴趣的朋友也可以去我的github点个star,你的支持是我持续输出的动力,谢谢!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92631.html

相关文章

  • JavaScript中让x==1&&x==2&&x==3等式成立演示

      要是别人问您:如何让 x 等于 1 且让 x 等于 2 且让 x 等于 3 的等式成立?  咋地,知道如何实现?想骂人有不  现在我们一起来分解思路:  我们先来讲讲宽松相等== 和严格相等 ===,这两个都能用来判断两个值是否相等,但们明确上文提到的等于指的是哪一种,二者的区别看下:  (1) 这两个基础直接的区别:  (1.1) 不同类型间比较,== 比较转化成同一类型后的值看值是否相等,...

    3403771864 评论0 收藏0
  • 通过JavaScript实现扑克牌游戏的示例代码

      我们说下想要实现,一副牌里有54张,我们可以知道 3 - 2 的牌总共有13张,这分为4个花色是 ♠️ ♥️ ♣️ ♦️ 另外加上2个大小王!第一步:形成一个数组, 就要写一个函数,利用牌数量和花色,这样可以用来形成一个双重循环将 number 里面的内容 和 flower 里面的内容 进行一个循环嵌入?最后在用 push 生成一个对象放到数组的后面?再到最后放入 大小王 。  constnu...

    3403771864 评论0 收藏0
  • JavaScript数组的9个方法示例

      今天主要就是汇总JavaScript数组的9中不同方法汇总,也将详细示例展示给大家。  如果你还不知道数组实例中迭代方法有什么区别,可以看下面这张图:  map  代表返回一个新的数组,且数组中的每一项都是执行过map提供的回调函数结果。  实现代码如下:  constmap=(array,fun)=>{   //类型约束   if(Object.prototype.toString.c...

    3403771864 评论0 收藏0
  • Python Pampy模式匹配库怎么使用呢?

      Python Pampy是Python模式中一个比较常见的数据库类型,它匹配到模式库中的内容还是比较的多的,代码库虽然只有150行,但是它的代码是更加的简洁的,能有效的提高我们的工作效率,那么,就具体的内容,下面就给大家详细解答下。  Pampy是哪路神仙  首先普及一下模式匹配。  模式匹配即给定某种模式,用这种模式去检查序列或字符串是否符合这种模式,这种技术在自然语言处理中经常使用。  P...

    89542767 评论0 收藏0
  • 解析JavaScript判断两个值相等的方法

      本篇文章主要是讲述在JavaScript中判断两个值相等,不要认为很简单,要注意的是在JavaScript中存在4种不同的相等逻辑。  ECMAScript 是 JavaScript 的语言规范,在ECMAScript 规范中存在四种相等算法,如下图所示:  上图中每个依次写下来,很多前端应该熟悉严格相等和非严格相等,但对于同值零和同值却不熟悉,现在就依次下面四种方法。  同值  同值零  非...

    3403771864 评论0 收藏0

发表评论

0条评论

light

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<