今天浏览一些技术网站,看到这个题目。虽然觉着代码这么写的可能性低之又低,但是却也考验对js了解的程度。

在 JavaScript 中 (a ==1 && a== 2 && a==3) 可能为 true 吗?解释说nothing is impossible!

这里是两个可能的答案:

<script>
    const a = {
        i: 1,
        toString: function () {
           return a.i++;
        }
    }

    if(a == 1 && a == 2 && a == 3) {
        console.log('Hello World!');
    }
</script>

<script>
    const a = {
        i: 1,
        valueOf: function () {
           return a.i++;
        }
    }

    if(a == 1 && a == 2 && a == 3) {
        console.log('Hello World!');
    }
</script>

最根本的还是强制类型转换。类型==,===运算符和强制转换:

先看个表达式:

<script>
    var res = "1.0e0" == { valueOf: function() { return true; } };
   console.log(res);
</script>

是的,这个结果也是 true。对于这个表达式我们能够注意到:它们的类型是不一样的。原因是在运算的时候进行了强制转换。在比较之前,它们被转换成了数字。字符串”1.0e0“被解析成数字1,而匿名对象通过调用自身的valueOf方法得到true,然后再转换成数字1。我们需要知道的是:

  1、如果表达式两边的数据类型不一致,==运算符两边会进行强制转换;

  2、此对象在被强制转换时,优先调用了自身的valueOf方法;(如果此对象没有valueOf方法或对象的valueOf返回的是false,则以上表达式结果为false)

  3、如果此对象没有valueOf方法,则会继续尝试调用toString方法

  4、如果将==运算符改成===运算符,则不会强制转换;

  5、如果表达式两边数据类型一致,==运算符和===运算符返回的结果是一致的

下图为==运算符针对不同类型参数的强制转换规则:

 规则看着挺复杂,不幸的是,它其实也是这么复杂。所以在比较操作中,如果不同类型进行比较,不建议使用==运算符,而是使用严格相等===运算符,因为使用严格相等运算符读者会非常清晰地知道:在比较中没有涉及任何强制转换。否则,你需要读者准确的记住这些强制转换规则以解读代码的行为。

  另外一个增加代码可读性的方法就是显示的进行数据类型转换:

代码1:

var today = new Date();

if(form.month.value == (today.getMonth() + 1) &&
   form.day.value == today.getDate()){
         //happy birthday...           
}

代码2:

var today = new Date();

if(+form.month.value === (today.getMonth() + 1) &&
   +form.day.value === today.getDate()){
         //happy birthday...           
}

很显然,代码2更加清晰地向读者传达了代码在做什么样的转换,它只是显示的使用Number函数或者一元运算符 + 将值转换为数字,而不要求读者记住这些转换规则。

版权声明:本文为yinn原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yinn/p/7495448.html