有趣的Javascript题:a为什么时会打印结果

 问题:

        var a = ? ;
        if (a == 1 && a == 2 && a == 3) {
            console.log('小样儿!')
        }

当a等于什么的时候,if条件成立,并打印?

初看这道题时一脸懵,a的值居然会随着判断条件不断累加,于是,大脑飞速运转,什么样的数据会随着操作而不断变化呢?思来想去也想不到这样的数据,所以只能利用巧妙方法了。

 解答:

方法一:利用对象的类型转换

        var a = {
            num: 1,
            toString: function () {
                return a.num++
            }
        };
        a.join = a.shift
        if (a == 1 && a == 2 && a == 3) {
            console.log('小样儿!')
        }

解释:

a == 1 && a == 2 && a == 3是一个短路逻辑与运算符,表示左边条件成立时才会继续向右判断,否则整个条件都为假。所以a的第一个值必须为1才能继续向右判断 ,由此可知a的值或者说是类型转换后的值是可以自增长的,Javascript中当遇到不同类型的值进行比较时,会根据类型转换规则试图将它们转换为同一类型再比较。比如Object类型与number类型进行比较时,Object类型会转换为number类型。转换时会尝试调用Object.valueOf()方法和Object.toString()方法来获取对应的数值基本类型。在上面的代码中,逻辑转换先调用了Object.valueOf()方法,如果返回的是对象,在接着调用头toString()方法。每次比较都会执行重写后的对象方法toString(),这个方法先返回属性num的值,然后再自增。执行a ==1时,对象a调用toString()方法返回了属性num值为1,此时a==1成立,接着a.num自增;以此类推,执行a==2和a==3都会成立,自然会打印结果。

方法二:利用数组的取值和类型转换

        var a = [1, 2, 3, 4];
        a.join = a.shift
        if (a == 1 && a == 2 && a == 3) {
            console.log('小样儿!')
        }

解释:

在 JavaScript 中,几乎所有的对象都是 Object 类型的实例,它们都会从Object.prototype继承属性,所以Array也是对象的继承类,它继承了Object的valueOf()和toString()方法,而且重写了toString()方法。

a.join  = a.shift这句话的意思是当数组因为调用toString()方法而 间接调用join()方法时,shift()方法替代join()方法,这样就相当于每次从a数组中移除第一个元素并返回第一个元素。所以当判断a==1时其实是从原数组中移除第一个元素,并返回第一个元素的值做判断,这样原数组就变成[2,3,4];接着a=2就相当于从新数组[2,3,4]中移除第一个元素并返回第一个元素做判断;接着再判断a==3。这样每次每个判断条件都能成立,所以会打印结果。

猜你喜欢

转载自blog.csdn.net/Celester_best/article/details/125436556
今日推荐