你真的理解==和===吗?

更新日期: 2018-12-11阅读: 2k标签: 表达式

开门见题

说出以下几个表达式的结果

var obj1 = { name: '张三'}
var obj2 = obj1
var obj3 = { name: '张三'}

null == undefined
123 == '123'
false == 0
NaN == false
obj1 == obj2
obj1 == obj3


补充知识

要想回答上述问题,必须理解js在执行==时候的一些数据转换规则和成文的规定。ECMA-262对==的约定如下:

x==y

  1. 如果x和y的类型相同,

    1. 如果x是undefined,return true
    2. 如果x是null,return true
    3. 如果x是Number

      1. x是NaN,return false
      2. y是NaN,return false
      3. x,y数值相同,return true
      4. x是+0,y是-0,return true
      5. x是-0,y是+0,return true
    4. 如果x是String,y必须和x长度内容都相同才return true,否则return false
    5. 如果x是Boolean,x,y相同return true,否则return false
    6. 如果x,y引用同一个对象,return true,否则return false
  2. x是null,y是undefined,return true
  3. x是undefined,y是null,return true
  4. x是Number,y是String,return x == ToNumber(y)
  5. x是String,y是Number,return ToNumber(x) == y
  6. x是Boolean,return ToNumber(x) == y
  7. y是Boolean,return x == ToNumber(y)
  8. x是String或Number,y是Object,return x == ToPrimitive(y)
  9. x是Object,y是String或Number,return ToPrimitive(x) == y
  10. return false


你可能注意到了这样两个函数

ToNumber()

参数类型结果
UndefinedNaN
Null+0
Booleantrue为1,false为+0
Number参数本身
String简单理解,能转换成数字的就会转换成数字,比如数字字符串,十六进制的数字等,转换失败则返回NaN(详见ECMA-262-9.3.1,内容较多,不展开叙述)
Object两步转换操作:1. ToPrimitive(input argument, hint Number) 2. ToNumber()

ToPrimitive()

参数类型结果
Undefined输入值
Null输入值
Boolean输入值
Number输入值
String输入值
Object调用DefaultValue方法

好吧,又多了一个DefaultValue方法

ToPrimitive()

细心的你发现上面ToNumber对于Object的转换里有这么一句ToPrimitive(input argument, hint Number),就是说调用ToPrimitive的时候,除了传入要转化的值,还传了一个hint参数,这个参数可以为Number,也可以为String。那么什么时候传入这两个参数,同时又有啥区别?

  • 如果参数是hint Number:
  1. 先执行valueOf,如果返回值是原始值,则返回原始值
  2. 否则执行toString,如果返回值是原始值,则返回原始值
  3. 报错
  • 如果参数是hint String:
  1. 先执行toString,如果返回值是原始值,则返回原始值
  2. 否则执行valueOf,如果返回值是原始值,则返回原始值
  3. 报错

如果input argument是内置的Date类型,则参数是hint String,否则默认hint Number


回到题目

说了这么多,我们回到上面的题目,一一解答:

  1. null == undefined。根据上面第二条,写的明明白白,结果是true。
  2. 123 == '123'。根据上面第四条return 123 == ToNumber('123'),而ToNumber('123')的结果为123,所以return 123 == 123,根据1-3-3,返回true。
  3. false == 0。根据上面第六条,return ToNumber(false) == 0,而ToNumber(false)的值为+0,所以+0 == 0,根据1-3-3,返回true。
  4. NaN == false。看到很多别的同学说这里是做了各种类型转换,其实我认为这里是由于没有匹配到任何规则,所以根据第十条返回false,也就是说并没有做什么类型转换。
  5. obj1 == obj2。根据1-6,由于obj1和obj2指向同一个引用,所以返回true。
  6. obj1 == obj3。根据1-6,由于obj1和obj2指向不同引用,所以返回false。


关于===

把上面题目中的==换成===,试问结果会发生怎样的变化?这里我就不说了,推理方式同上,根据如下规则,答案请各位看官自行补充。
2934?ynotemdtimestamp=1532482432857

x===y

  1. 如果x,y类型不同,return false
  2. 如果x是undefined,return true
  3. 如果x是null,return true
  4. 如果x是Number

    • 如果x是NaN,return false
    • 如果y是NaN,return false
    • x,y数值相同,return true
    • x是+0,y是-0,return true
    • x是-0,y是+0,return true
    • return false
  5. 如果x是String,y必须和x长度内容都相同才return true,否则return false
  6. 如果x,y引用同一个对象,return true,否则return false


来源:https://segmentfault.com/a/1190000015757181


链接: https://fly63.com/article/detial/1544

js中表达式 >>> 0 浅析

今天在看lodash的源码中slice这个函数实现的时候发现了里面有这么一行代码:>> 和 >>>有什么不一样、移位0有什么意义、Uint32类型是如何转换的

什么是后缀表达式?

后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。

js中两个表达式运算结果的解析: []==![] 和{}==!{}

[]==![] 感叹号!的优先级最高,因此先计算![], 其结果为 false, 所以表达式被转换成: []==false.遇到Boolean类型,需要先转换成Number类型,所以表达是变成 []==0,0是基础类型,[]是引用类型

js正则表达式之解决html解析<>标签问题

以博客写文章为例,有的时候我们不经意间写的字符串带标签,然后浏览器将其解析了,实际上我们并不希望其被解析,于是可通过核心代码解决该问题。

JS三元表达式

三元表达式怎么用?三元表达式怎么就有用了?代码量会减少这是事实,配合箭头函数写函数式代码,哪个更易读这个就是主观判断了,见仁见智:

JS基础语法:分支语句之三元表达式

三元表达式,语法:* var 变量=表达式1?表达式2:表达式3;* 执行过程:* 表达式1的结果是true还是false,如果是true则执行表达式2,然后把结果给变量

20个稀奇古怪的 JavaScript 表达式,你要挑战回答一下嘛

JavaScript是一种非常容错的编程语言,许多在其他编程语言中不合法的表达式在JavaScript中都能正常工作。这导致了很多奇怪的代码。你想挑战它吗?

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!