• JS中的“==”和“===”的区别


    • 前言:

    在同类型变量的比较中,"==="会直接返回true,而非同类型中,"=="直接会先将两个比较值转换为同一类型,再进行比较。

    这里的转换就是"隐式转换",例如,以下几种:

    "1" ==  1;            // true
    1 == "1";             // true
    0 == false;           // true
    

    那下面这个怎么解释?

    ![] == []
    //还有下面 a
    = [] a == !a && a == a //true

      大部分教程和书中,都建议使用"===",而不建议使用"==",因为"==="可以比年不同类型变量之间的比较,而且速度会更快。但是,我们还是应该搞清楚"=="存在的原理,并进行合理的使用。

    • "=="作用规则

    当要比较的值类型相同,值为true,不同即为false。

    来看下,值类型不相同的。

    MDN文档中,有几条规则:

    1、 当数字与字符串进行比较时,会尝试将字符串转换为数字值;

    2、如果操作数之一是Boolean,则将布尔操作数转化为1 或 0;

    3、 如果操作数之一是对象,另一个数字后字符串,会尝试使用对象的valueOf()和toString()方法讲对象转换为数字或字符串;

    4、 null == undefined 为true,此外通常情况下null和undefined与其他对象都不相等。

    "![] == []",就相当于"false == []",然后由Boolean操作数,还可以转换为"0 == []" ,而"[]"转换为数字是0,所以返回true。

    • 对象中的valueOf和toString,转换的时候那个优先级高

    对象在隐式转换的时候,会尝试调用valueOf 和 toString函数,向字符串或者数字转换。那优先会采用哪一个函数的值?

    实验:

    const a = {}
    a.valueOf = () => 1
    a.toString = () => 2
    console.log(a == 1, a == 2) // true, false
    
    const b = {}
    b.valueOf = () => null // 优先级高于toString,比较直接返回false
    b.toString = () => '1'
    console.log(b == 'null', b == 1, b == '1') // false, false, false
    
    const c = {}
    c.valueOf = () => ([]) // 返回非基本值,将尝试取toString比较
    c.toString = () => '1'
    console.log(c == 'undefined', c == '1') // false, true
    
    const d = {}
    d.valueOf = () => ([]) // 返回非基本值
    d.toString = () => ([])
    console.log(d == 'undefined', d == '1') // 比较报错:不能转为原始值

    经过以上测试,valueOf 的优先级高于toString的优先级,而且valueOf和toString都会返回原始值(“String”,“Number”,“Boolean”,“null”,“undefined”),如果返回的是“null”或者是“undefined”,比较返回false,否则根据另一个比较值转为字符串或者数字进行比较;如果都不返回原始值,则比较操作将会报错。

    • 显式转换

    objA == 'abc' 的比较并不同于简单地将objA显式转换为字符串进行比较,即:objA == 'abc' 与 String(objeA) == 'abc' 结果并不一定相同(显式转换直接走toString):

    const e = {}
    e.valueOf = () => 1
    e.toString = () => '2'
    console.log(e == 1, e == '1', String(e) == '1',  String(e) == '2') // true, true, false, true
    • ES6中更高优先级的转换函数:Symbol.toPrimitive属性

    Symbol.toPrimitive是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数。该函数被调用时,会被传递一个字符串参数 hint ,表示要转换到的原始值的预期类型。 hint 参数的取值是 "number""string" 和 "default" 中的任意一个。对于”==“操作符,hint传递的值是”default“。

    const a = {}
    a[Symbol.toPrimitive] = (hint) => {
        if (hint == 'number') return 1
        if (hint == 'string') return 2
        return 3
    }
    a.valueOf = () => 4
    a.toString = () => 5
    console.log(a == 1, a == 2, a == 3, a == 4, a == 5) // false, false, true, false, false

    如果使用Number或者String强制转换a,则传入的”hint“会是”number“或者”string“。

  • 相关阅读:
    避免Node.js中回调地狱
    XSS和CSRF攻击
    浅析SPDY
    移动端的图片优化
    js中的事件委托技术
    js的5种继承方式——前端面试
    深入理解前端跨域问题的解决方案——前端面试
    javascript中“use strict”的好处和坏处
    Http请求中POST与GET的区别——前端面试
    滚动条离底部的距离小于某个值
  • 原文地址:https://www.cnblogs.com/Archie2018/p/13856532.html
Copyright © 2020-2023  润新知