zoukankan      html  css  js  c++  java
  • (a ==1 && a== 2 && a==3) 有可能是 true 吗?

      工作之余逛知乎的时候看到一个有意思的讨论,(a ==1 && a== 2 && a==3) 有可能是 true 吗?啊?一个变量同时满足三个条件?扯呢?

      当然是我太天真了,既然有讨论,就一定会有答案,结果答案还不止一个,真的是学习了,也有原文讨论过这个问题,觉得很有意思就拿来记录一下分享一下。

      这是一道某科技公司问到的面试题。

      方法一:

      利用松散相等运算符 == 的工作原理,你可以简单地创建一个带有自定义toString( 或者 valueOf)函数的对象,在每一次使用它时候改变它所的返回值,使其满足所有三个条件。

    const a = {
      i: 1,
      toString: function () {
        return a.i++;
      }
    }
    if(a == 1 && a == 2 && a == 3) {
      console.log('Hello World!');
    }
    // Hello World!

      之所以会得到如此结果,是由于表达式中使用了松散相等的运算符 ==。使用松散相等时,如果其中一个操作数与另一个类型不同,则 JS 引擎将尝试将一个操作转换为另一个类型。在左边对象、右边的数字的情况下,它会尝试将对象转换为一个数,首先通过调用 valueOf 如果是可调用的。否则,它会调用toString方法。我使用toString仅仅是因为它是我的第一反应,valueOf 会更合理。如果我不从toString返回一个字符串(而是返回数字),JS 引擎会尝试将字符串转换为一个数字,虽然有一个稍长的路径,但它仍然会给我们同样的结果。

      方法二:

      我不可否认——其他答案无疑是正确的,但你真的不能过错下面的代码:

    var aᅠ = 1;
    var a = 2;
    var ᅠa = 3;
    if(aᅠ==1 && a== 2 &&ᅠa==3) {
        console.log("Why hello there!")
    }

      请注意if 语句中的奇怪间距。它是半宽度韩文“ᅠ”。这是一个 Unicode 空格字符,但是 ECMAScript 不将其解释为一个空格 —— 这意味着它是一个有效的标识符。因此有三个完全不同的变量,一个是a后加半宽度韩文,一个是a, 一个是a前加半宽度韩文。。。

      

      方法三:

    var val = 0;
    Object.defineProperty(window, 'a', {
      get: function() {
        return ++val;
      }
    });
    if (a == 1 && a == 2 && a == 3) {
      console.log('yay');
    }

      使用一个get,让 a 的返回值为三个不同的值。然而这并不意味着我们应该在真正的代码中使用。

      总结

      1. 利用松散相等运算符 == 的原理,自定义 toString 和 valueOf 返回对应值

      2. 利用半宽度韩文等特殊字符,玩“障眼法”,本质上其实并没有做到题设

      3. 劫持 JS 对象的 getter,不过这种方式对于严格相等 === 同样有效

    原文链接:http://elevenbeans.github.io/2018/01/23/nothing-is-impossible-for-javascript/

  • 相关阅读:
    .NET_.NET 发布(publish)网站_012
    Oracle 11g Release 1 (11.1) 单行函数——日期函数
    Oracle 11g Release 1 (11.1) SQL_层级查询(概)
    C# 清理非托管资源
    NChain 0.1 项目——但愿是根救命稻草
    人工智能——神经网络
    概念——都有哪些 Web 服务方式
    从 Fibonacci 数列看“动态规划”思想
    QR 码
    Oracle 11g Release 1 (11.1) 表空间——创建和扩展永久表空间
  • 原文地址:https://www.cnblogs.com/zheng577564429/p/8358441.html
Copyright © 2011-2022 走看看