js中笼统相称==

Javascript中笼统相称比较算法

undefined==null
//true
[]==[]
//false
[]==![]
//true
{}==!{}
//false
![]=={}
//false
[]==!{}
//true
[1,2]==![1]
//false

大抵引见一下JS的数据范例

ES5的数据范例分为6种:Undefined Null String Number Boolean Object,假如再加上ES6Symbol数据范例,一共7种;

nullundefined的区分:

  1. null形貌一个空值(空的对象援用即空指针),null被当作一个对象,typeOf null输出为'Object'(算是一个bug吧),Number(null)输出为0undefined是预定义的全局变量,示意“缺乏值”,typeOf undefined输出为'undefined'Number(undefined)输出为NaN
  2. null是一个关键字,而undefined并非一个关键字;

原始值观点

js的数据范例实在能够分为两种:原始范例援用范例原始范例又称简朴范例基础范例,包含UndefinedNullBooleanNumberString五种。援用范例又称庞杂范例,即Object原始范例援用范例离别称为原始值庞杂值

简朴的说:原始值是牢固而简朴的值,是存放在栈(stack)中的简朴数据段,也就是说,它们的值直接存储在变量接见的位置,原始范例的值被称为原始值

原始范例(primitive type)有以下五种范例:Undefined,Null,Boolean,Number,String

typeOf运算符:

前提返回值
假如变量是undefined范例undefined
假如变量是Boolean范例boolean
假如变量是Number范例number
假如变量是String范例string
假如变量是Null范例object
假如变量是援用范例object

笼统相称算法

用Type(z)代表z的数据范例,比较运算 x==y,个中x和y是值,发生true或false。
    1.Type(x)与Type(y)雷同:
        a.假如Type(x)为Undefined或Null,则返回true
           
        b.假如Type(x)为Number,则:
            i.若x为NaN,返回false
            ii.若y为NaN,返回false
            iii.若x与y数值相称,返回true
            iiii.若x为+0,y为-0,返回true
            iv.若x为-0,y为+0,返回true
            v.返回false
            
        c.假如Type(x)为String,则x和y对应位置的字符完整一样才返回true,不然返回false,
        
        d.假如Type(x)为Boolean,则雷同值返回true,不然false
        
        f.当x和y援用统一对象时,返回true,不然,返回false
            
    2.x为undefined,y为null,返回true,反之亦然
            
    3. Type(x)为String,Type(y)为Number,则返回比较ToNumber(x) == y,反之亦然
            
    4.Type(x)为Boolean,则返回比较ToNumber(x)==y的效果,反之亦然

    5.Type(x)为String或Number,Type(y)为Object,则返回比较ToPrimitive(y) == x
    
    6.返回false

再来看看ToBooleanToNumberToPrimitive三个运算符的定义:

ToBoolean
输入范例效果
Undefinedfalse
Nullfalse
Boolean不转换
Number假如参数是-0+0NaN,效果为false,不然为true
String假如参数是空字符串(长度为零),效果为false,不然为true
Objecttrue
ToNumber
输入范例效果
UndefinedNaN
Null+0
Boolean参数为true,效果为1,参数为false,效果为+0
Number不转换
String拜见下文的文法和诠释
Object运用下步骤:1、设原始值为ToPrimitive(输入参数,暗示,数值范例)。2、返回ToNumber(原始值)
ToPrimitive

ToPrimitive运算符吸收一个值,和一个可选的希冀范例作参数。ToPrimitive运算符把其值参数转换为非范例对象。假如对象有才能被转换为不止一种原语范例,能够运用可选的 希冀范例 来暗示谁人范例。

输入范例效果
Undefined不转换
Null不转换
Boolean不转换
Number不转换
String不转换
Object返回该对象的默认值。对象的默认值由希冀范例传入作为hint参数挪用对象内部要领[DefaultValue]获得

** ToPrimitive这个要领,参照火狐MDN上的文档引见,大抵意义以下:

ToPrimitive(obj,preferredType)

JS引擎内部转换为原始值ToPrimitive(obj,preferredType)函数接收两个参数,第一个obj为被转换的对象,第二个
preferredType为愿望转换成的范例(默以为空,接收的值为Number或String)

在实行ToPrimitive(obj,preferredType)时假如第二个参数为空而且obj为Date的实例时,此时preferredType会
被设置为String,其他情况下preferredType都会被设置为Number假如preferredType为Number,ToPrimitive执
行历程如
下:

  1. 假如obj为原始值,直接返回;
  2. 不然挪用 obj.valueOf(),假如实行效果是原始值,返回之;
  3. 不然挪用 obj.toString(),假如实行效果是原始值,返回之;
  4. 不然抛非常。

假如preferredType为String,将上面的第2步和第3步换取,即:

  1. 假如obj为原始值,直接返回;
  2. 不然挪用 obj.toString(),假如实行效果是原始值,返回之;
  3. 不然挪用 obj.valueOf(),假如实行效果是原始值,返回之;
  4. 不然抛非常

Ok,到现在,我们须要相识,toString要领和valueOf要领;

toString用来返回对象的字符串示意。

    let obj = {name:"Tom"}; //"[object Object]"
    let obj = {}; //"[object Object]"
    let arr = [1,2];    //"1,2"
    let arr = [];    //""
    let str = "1";      //"1"
    let num = 1;        //"1"
    let boo = true;     //"true"
    let date = new Date();      //"date Sat Mar 24 2018 00:23:12 GMT+0800 (CST)"
    let nul = null;     //报错
    let und;            //报错

valueOf要领返回对象的原始值,多是字符串数值bool值等,看详细的对象。

    let obj = {name:"Tom"}; //{name:"Tom"}
    let arr = [1,2];    //[1,2]
    let str = "1";      //"1"
    let num = 1;        //1
    let boo = true;     //true
    let date = new Date();      //1521822331609
    let nul = null;     //报错
    let und;            //报错

简朴明白:原始值指的是[Null,Undefined,String,Boolean,Number]五种基础数据范例之一

总结一下==运算的划定规矩:


1. undefined == null,效果是true。且它俩与一切其他值比较的效果都是false。

2. String == Boolean,须要两个操作数同时转为Number。

3. String/Boolean == Number,须要String/Boolean转为Number。

4. Object == Primitive(原始值),须要Object转为Primitive(详细经由过程valueOf和toString要领)。

栗子

undefined==null
//true
[]==[]
//false
[]==![]
//true
{}==!{}
//false
![]=={}
//false
[]==!{}
//true
[1,2]==![1]
//false

undefined==null

效果为true,不必诠释了,记着就好了

[]==[]

  1. 先看这两个的范例,typeOf([])获得的是'object'
  2. 笼统相称算法1-f,援用统一范例的才算相称
  3. 返回false

[]==![]

  1. !取反运算符的优先级高于==,因而先算出![]这个得值,再去运用笼统相称算法举行比较
  2. 取反运算符会先挪用要领ToBoolean,再去取反
  3. ToBoolean([])返回的是true,因而![]应该为false
  4. []==![]转换为了[]==false
  5. 依据笼统相称算法4条,则我们能够比较[]==ToNumber[false]的值,则能够获得[]==0
  6. 再依据笼统相称算法5条,比较ToPrimitive([])==0
  7. 因为[]不是Date范例,所以先获得[].valueOf()的值,为[]
  8. 再获得[].toString()的值,为""的字符串
  9. 以上7,8部可合并为一步即比较[].valueOf().toString(),获得""字符串,此时[]转换为了原始值范例(即五种基础范例中的一种)了。
  10. 依据笼统相称算法3,则能够比较ToNumber("")==0,到这里[]==![]转化为了0==0
  11. 返回true

{}==![]

  1. 表达式右边,反复上一次的1-5步,能够获得{}==0
  2. 依据笼统相称算法5条,ToPrimitive({})==0,获得{}.valueOf().toString()获得一个字符串"[object Object]",是原始范例
  3. 依据笼统相称算法3,末了比较ToNumber("[object Object]")==0,转变为1==0
  4. 返回false

其他的栗子本身算一算吧

结语

本身从新写了写一遍整理了一下思绪,假如什么地方没有讲清楚,请指出;

参考:

    原文作者:John
    原文地址: https://segmentfault.com/a/1190000013956124
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞