今天浏览一些技术网站,看到这个题目。虽然觉着代码这么写的可能性低之又低,但是却也考验对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 JavaScript!');
}
</script>

运行代码

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

先看个表达式:

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

运行代码

是的,这个结果也是 true。

对于这个表达式我们能够注意到:

它们的类型是不一样的。原因是在运算的时候进行了强制转换。在比较之前,它们被转换成了数字。

字符串”1.0e0“被解析成数字1,而匿名对象通过调用自身的valueOf方法得到true,然后再转换成数字1。

这也是a可以同时为1,2,3的原因。

我们需要知道的是:

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

2、此对象在被强制转换时,会自动优先调用了自身的valueOf方法

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函数或者一元运算符 + 将值转换为数字,而不要求读者记住这些转换规则。

(a == 1 && a == 2 && a == 3),何时为true?的更多相关文章

  1. Mapreduce的文件和hbase共同输入

    Mapreduce的文件和hbase共同输入 package duogemap;   import java.io.IOException;   import org.apache.hadoop.co ...

  2. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  3. mapreduce中一个map多个输入路径

    package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...

  4. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  5. 【.net 深呼吸】细说CodeDom(8):分支与循环

    有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...

  6. H5实现摇一摇技术总结

    摇一摇遇到的问题 一.如何对摇晃效果进行反馈 刚开始的处理方式是,摇晃过程中不做任何处理,但后来反馈说这种效果不好,好像就没有摇动一样,如果声音也不响的话,就真的和什么都没发生一样. 后来想了想,加入 ...

  7. Fis3前端工程化之项目实战

    Fis3项目 项目目录结构: E:. │ .gitignore │ fis-conf.js │ index.html │ package.json │ README.md │ ├─material │ ...

  8. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  9. Unity3d学习 相机的跟随

    最近在写关于相机跟随的逻辑,其实最早接触相机跟随是在Unity官网的一个叫Roll-a-ball tutorial上,其中简单的涉及了关于相机如何跟随物体的移动而移动,如下代码: using Unit ...

  10. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

随机推荐

  1. android 串口开发第二篇:利用jni实现android和串口通信

    一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...

  2. 小白的 MySQL 笔记(一)

    来自 stackoverflow 的内容居多. 1- MySQL VARCHAR size? 2- 数据库设计范式 3- What is InnoDB and MyISAM in MySQL ? 4- ...

  3. [Find the last digit when factorial of A divides factorial of B]

    Given two numbers A and B. The task is to compute the last digit of the resulting F, where F= B! / A ...

  4. bzoj 2298: [HAOI2011]problem a

    Description 一次考试共有n个人参加,第i个人说:"有ai个人分数比我高,bi个人分数比我低."问最少有几个人没有说真话(可能有相同的分数) Input 第一行一个整数n ...

  5. js的Date对象

    1.构造Date对象 var dt = new Date(); //获取当地包含日期和时间的对象,格式为:Thu Aug 31 2017 09:15:43 GMT+0800 (中国标准时间) 2.使用 ...

  6. js获取字符串最后一位方法

    方法一:运用String对象下的charAt方法 charAt() 方法可返回指定位置的字符. str.charAt(str.length – 1) 请注意,JavaScript 并没有一种有别于字符 ...

  7. [编织消息框架][JAVA核心技术]动态代理应用3

    我们先使用懒处理实现提取接口类上的元信息: public abstract class QRpcFactory { public static <T> T loadProxy(Class& ...

  8. css实现多行文本溢出显示省略号(…)全攻略

    省略号在ie中可以使用text-overflow:ellipsis了,但有很多的浏览器都需要固定宽度了,同时ff这些浏览器并不支持text-overflow:ellipsis设置了,下文来给各位整理一 ...

  9. KVO键值观察的具体实现

    1.KVO简介 KVO是Objective-C对观察者设计模式的一种实现,它提供一种机制,指定一个被观察对象(如A类),当对象中的某个属性发生变化的时候,对象就会接收到通知,并作出相应的处理.在MVC ...

  10. Linux下Jdk的安装和jdk环境变量的设置

    我们在Linux下安装系统软件的时候,经常遇到一些系统环境变量配置的问题.什么是环境变量?如何定制环境变量?我将在下面做一些介绍.一.什么是环境变量?Linux是一个多用户的操作系统.多用户意味着每个 ...