zoukankan      html  css  js  c++  java
  • 偷偷运行的逻辑

    将写作当成兴趣,并一直进行下去。曾经这是个小小的奢望,现在已经在逐步的实现中。

    长话短说,既然是技术文,就不发这么多感慨了,接下来,一起进入今天的正题吧。

    今天给大家分享的是 JavaScript 中的隐式类型转换问题。相信很多的小伙伴都曾被它困扰过,不论是开发中还是面试过程中。期望今天的分享能给你带来不一样的理解。也能让你之后不再为此烦恼。

    1. 基本数据类型

    我们都知道,在 javascript 中一共有 7 中数据类型。分别是 Object, Null, Undefined, String, Number, Boolean, Symbol。这些东西我们在平时的开发过程中每天无时无刻不在接触,这里我们不多赘述。

    2. 强制类型转换

    平时的使用过程中,我们会遇到很多数据类型不一致的问题,同样,强制将不同的数据类型转换为相同的数据类型也是很正常的操作;接下来,我们看看都有什么样的强制转换方法:

    2.1 字符串 -> 数字

    1. parseInt
    parseInt('123') // 123
    parseInt('123abc') // 123
    parseInt('12.3abc') // 12
    parseInt('abc123') // NaN
    

    解释:

    此方法只转换 以数字开头的,直到不是数字,然后转换结束,如果字符串不是以数字开头,则转换为 NaN

    2. parseFloat
    parseFloat('123') // 123
    parseFloat('12.3abc') // 12.3
    parseFloat('1.2.3abc') // 1.2
    parseFloat('abc1.23') // NaN
    

    解释:

    规则同 parseInt ,只是注意小数点的转换,只能转换一个小数点,如果是多个小数点,则只保留一个。

    3. Number
    Number('123') // 123
    Number('12.3abc') // NaN
    Number('1.2.3abc') // NaN
    Number('abc1.23') // NaN
    

    解释:

    此方法只转换 全数字 的字符串,如果字符串不是全数字。如'12.3abc','1.2.3abc','abc1.23'………… 的情况,统一转换为 NaN

    4. 位运算

    位运算的使用在前端是特别少的,以至于很多前端人员不清楚具体使用。下面我们来看看,如何使用位运算将字符串转换为数字

    主要有以下几种操作方式可做转换

    • ~
    • << 左移
    • >> 右移

    对于位运算的实际运算方式我们暂不做描述,本次只看如何使用它们将字符串转为数字

    ~~'123'    // 123 (这里是两个 ~~ 波浪线)
    '123' << 0 // 123
    '123' >> 0 // 123
    

    解释:

    使用方法跟 Number 相同。都是只能转换全数字的字符串。不为全数字的字符串,~转换为 NaN ,另外两种转换为 0

    2.2 数字 -> 字符串

    1. 使用 + 运算符。
    '' + 123 // '123'
    
    2. 使用 toString 方法
    let num = 123
    num.toString() // ‘123’
    
    3. 使用 String 方法
    let num = 123
    String(num) // '123'
    

    2.3 转换为布尔值

    1. !! 方法。(双重否定即为肯定。使用双重非可以得到原始值转换的布尔值)
    let num = 123
    !!num // true
    
    let str = '123'
    !!str // true
    
    2. Boolean 方法
    let num = 123
    let str = '123'
    Boolean(123) // true
    Boolean('123') // true
    

    注意:

    JavaScript 中为 false 的情况:

    • '',"" 空字符串
    • 0 数字 0
    • undefined
    • null
    • NaN
    • false

    3. 隐式类型转换

    3.1 可触发隐式类型转换的操作

    • 四则运算 +, -, *, /
    • 比较 > < >= <= ==
      • 注意: === 是不会触发隐式类型转换的。
    • 判断 if, while

    3.2 toStringvalueOf 说明

    此两种方法是将复杂数据类型转换为原始值输出。

    1. 调用 valueOf 方法后
    • String, Number, Boolean 返回的分别是 字符串值,数字值,布尔值。
    • Object, Array, Function 返回的是自身
    • Date 返回的是从开始到现在的毫秒值
    2. 调用 toString 方法后
    • String, Number, Boolean 返回的本别是字符串类型的值
    • Object 返回的是 [object Object]
    • Array 返回的是 空字符串。因为在 Array 中重写了这个方法
    • function 返回的是函数本身的字符串
    • Date 返回的是时间,并非毫秒数

    注意:

    在获取原始值(toPrimitive)时,会先调用 valueOf 方法,如果返回的不是原始值(也就是说返回的不是基本数据类型),则会继续调用 toString 方法。如果还不是原始值。则会报错。

    3.3 具体实例解析

    请在查看解析之前尝试解答下方问题

    // 数组
    [] == ![]   // 1
    [] == []    // 2
    [] == false // 3
    [] == true  // 4
    [1] == 1    // 5
    [] == 0     // 6
    [12] < [13] // 7
    
    // 对象
    {} == {}    // 8
    {} == !{}   // 9
    {} != {}    // 10
    
    // 结合版
    [] + {}     // 11
    {} + []     // 12
    {} + {}     // 13
    [] + []     // 14
    {} + 1      // 15
    1 + {}      // 16
    

    答案来咯,准备好了没

    1. [] == ![] 执行步骤
    // 将原题中的 ![] 转换为原始值 --> ![] 为false
    [] == false
    // 将 [] 转换为原始值 [].valueOf() 返回自身,继续调用 toString 返回 空字符串
    '' == false
    // 将空字符串转换为 布尔值,空字符串为false
    false == false
    // 得到结果为 [] == ![] --> true
    
    2. [] == []
    比较的是地址,两个数组的地址不相同。结果为false
    
    3. [] == false

    解答步骤同第一题[] == ![]

    4. [] == true

    解答步骤同第一题[] == ![]

    5. [1] == 1
    // 将 [1] 获取原始值, 调用 valueOf 返回自身,继续调用 toString 返回 '1'
    1 == 1
    // 得到结果 [1] == 1 --> true
    
    6. [] == 0
    // 将 [] 获取原始值, 调用 valueOf 返回自身,继续调用 toString 返回 ‘’
    ‘’ == 0
    // 将空字符串转换为数字 '' --> 0
    0 == 0
    // 得到结果 [] == 0 --> true
    
    7. [12] < [13]
    // 将左右都转换为原始值
    '12' < '13'
    // 得到结果 true
    
    8. {} == {}

    [] == []

    9. {} == !{}

    [] == ![] 不同的是,这里的 {} 转化为字符串之后为[object Object] 。 所以结果与 [] == ![] 相反

    10. {} !== {}

    {} == {} 反结果

    11. [] + {}
    // 将左右同时获取原始值。
    '' + '[object Object]' = '[object Object]'
    
    12. {} + []

    如果右边的值不值一个字典格式,则会将大括号当成一个空块儿处理。也就是说此时的表达式可以被转换成如下表达式+ [],然后将 [] 先转为空串,然后转换为数字,得到数字0

    所以: {} + [] == 0

    13. {} + {}

    左右两边都做对象处理,获取原始值

    '[object Object]' + '[object Object]' = '[object Object][object Object]'
    
    14. [] + []

    获取左右的原始值,都转换为了空字符串。然后做字符串拼接

    '' + '' = ''
    
    15. {} + 1

    {} + [] ,可变形为 + 1

    16. 1 + {}

    将右方的 {} 获取原始值,得到 '[object Object]' ,原式可变形为

    1 + '[object Object]' = '1[object Object]'
    

    4. 补充点

    • NaN 与任何值都不相等,包括它本身(这得多很,自己跟自己都不相等)
    • undefined 参与的任意一个四则运算,结果都为 NaN
    • 布尔值 true 转数字时,转为 1false 转为数字时为 0
    • 字符串之间比较大小,实际比较的是字符编码。如:a > A = 97 > 65 = true

    好了,今天的文章就分享到这儿咯,并没有写太多的概念,只是让大家来多看下实际运行的结果。一通则百通,知晓了实际运行的过程,再遇到相似的问题就游刃有余了。

  • 相关阅读:
    gearman任务分发改进
    gearman实现任务分发
    BeanStalkd 做队列服务
    Tomcat各种日志的关系与catalina.out文件的分割
    数据库系统原理-关系数据库的规范化理论总结
    MySQL配置参数innodb_flush_log_at_trx_commit
    gRPC快速入门
    使用vagrant和kubeadm搭建k8s集群
    VS项目属性中的C/C++运行库:MT、MTd、MD、MDd
    消除C++中警告代码
  • 原文地址:https://www.cnblogs.com/yancyCathy/p/13619793.html
Copyright © 2011-2022 走看看