zoukankan      html  css  js  c++  java
  • 数据类型回顾——数据类型转换(显式和隐式)—JS学习笔记2015-6-3(第47天)

    对于JS这种语言来说,因为它是一种动态类型语言,变量是没有类型的,可以随时赋予任意值。

    但是,数据本身和各种运算是有类型的,因此运算时变量需要转换类型。

    大多数情况下,这种数据类型转换是自动的,但是有时也需要手动强制转换。

    首先看下强制类型转换(显式)

    之前提到的Namber、parseInt、parseFloat 都是强制类型转换;

    这里在看阮一峰博客(http://javascript.ruanyifeng.com/grammar/conversion.html#toc1)

    Number方法的转换,这里再做下记录:

    (1)原始类型值的转换规则

    • 数值:转换后还是原来的值。

    • 字符串:如果可以被解析为数值,则转换为相应的数值,否则得到NaN。空字符串转为0。

    • 布尔值:true转成1,false转成0。

    • undefined:转成NaN。

    • null:转成0。

    (2)对象的转换规则

           对象的转换规则比较复杂。

    1. 先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串和布尔值),则直接对该值使用Number方法,不再进行后续步骤。

    2. 如果valueOf方法返回复合类型的值,再调用对象自身的toString方法,如果toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤。

    3. 如果toString方法返回的是复合类型的值,则报错。

    也提到了2种妙味课堂老师暂时没提到的方法:

    String函数:强制转换成字符串

    (1)原始类型值的转换规则

    • 数值:转为相应的字符串。

    • 字符串:转换后还是原来的值。

    • 布尔值:true转为“true”,false转为“false”。

    • undefined:转为“undefined”。

    • null:转为“null”

    (2)对象的转换规则

        如果要将对象转为字符串,则是采用以下步骤。

    1. 先调用toString方法,如果toString方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。

    2. 如果toString方法返回的是复合类型的值,再调用valueOf方法,如果valueOf方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。

    3. 如果valueOf方法返回的是复合类型的值,则报错。

    // String方法的这种过程正好与Number方法相反

    还有阮老师也提到了,布尔值转换

    Boolean函数:强制转换成布尔值

    (1)原始类型值的转换方法

    以下六个值的转化结果为false,其他的值全部为true。

    • undefined
    • null
    • -0
    • +0
    • NaN
    • ''(空字符串)

    (2)对象的转换规则

    所有对象的布尔值都是true,甚至连false对应的布尔对象也是true。

    Boolean(new Boolean(false))
    // true

    请注意,空对象{}和空数组[]也会被转成true。

    Boolean([]) // true
    
    Boolean({}) // true




    下面谈下隐式类型转换,或者说(js内部自动转换)
    那么什么时候会发生隐式类型转换呢?

    当遇到以下几种情况,JavaScript会自动转换数据类型:

    • 不同类型的数据进行互相运算;

    • 对非布尔值类型的数据求布尔值;

    • 对非数值类型的数据使用一元运算符(即“+”和“-”)。

    首先妙味老师提到的集中隐式类型转换情况:

    隐式类型转换:
    +           200 + '3' 变成字符串
    - * / %         '200' - 3 变成数字
    ++ --        变成数字
    > <         数字的比较 、字符串的比较
    ! 取反            把右边的数据类型转成布尔值
    ==

    // alert( Number('……') ); NaN
    // alert( '……'-9 ); NaN


    //NaN 数据类型转换失败的时候,会返回NaN;

    // alert( '2' == 2 );

    // alert('10'>9) 返回true, 此时是数字的比较
    // alert( '10000000' > '9' ); 返回false,此时是字符串的比较,比较的是二者的编码;
    // > < 是数字的比较与字符串的比较

    // alert(!'ok'); 这时候返回false,为什么?
    // 看了阮一峰的JS教程,我才明白,在预期为布尔值的地方,系统会自动调用内部的Boolean方法来转换
    // Boolean方法 可以将任意类型的变量转为布尔值

    另外需要一提的是 + 运算符,

    有运算中存在a、 字符串的情况   // 两个运算子之中,只要有一个是字符串,则另一个不管是什么类型,都会被自动转为字符串,然后执行字符串连接运算

                     b、两个运算子都为数值或布尔值   //   这种情况下,执行加法运算,布尔值转为数值(true为1,false为0)

                 C、运算子之中存在对象

                         运算子之中存在对象(或者准确地说,存在非原始类型的值),则先调用该对象的valueOf方法。如果返回结果为原始类型的值,则运用上面两条规则;否则继续调用该对象的toString方法,对其返回值运用上面两条规则。 (这一块暂时还不理解,等学到object之后再仔细研究)

    关于两个等号的数值转换

    详见司徒正美的博客:http://www.cnblogs.com/rubylouvre/p/3990290.html
    另外为了避免这一问题的出现,大多数公司可能都要求,禁止使用双等号,直接使用三等号就好了
    /*
    这里说的隐性类型转换,是==引起的转换。

    如果存在NaN,一律返回false
    再看有没有布尔,有布尔就将布尔转换为数字
    接着看有没有字符串, 有三种情况,对方是对象,对象使用toString进行转换;对方是数字,字符串转数字;对方是字符串,直接比较;其他返回false
    如果是数字,对方是对象,对象取valueOf进行比较, 其他一律返回false
    null, undefined不会进行类型转换, 但它们俩相等
    这个顺序一定要死记,这是面试时经常问到的。

    下面是一些杂题,自己做做

    0 == undefined // false

    1 == true // true

    2 == {valueOf: function(){return 2}} // true

    NaN == NaN // false

    8 == undefined // false

    1 == undefined // false

    null == {toString: function(){return 2}} // false

    0 == null // false

    null == 1 // false



    { toString:function(){ return 1 } , valueOf:function(){ return [] }} == 1

    */

     

    还有慕课老师PPT(帮助理解):

    由于数据类型存在隐式转换,所以按照阮老师建议是:

    由于自动转换有很大的不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String方法进行显式转换

    关于加、 减符号,慕课网《深入浅出javascript》当中也有提到

    利用这种隐式转换的特性,如果我们想让那个一个变量的数据类型转换为数字,那么 num - 0 ; 此时这个num就是被隐式转换成了数字;

    同理,想让一个变量的数据类型转换为字符串,那么 num + '' ;  变量加上一个空的字符串,此时num就被转换成了字符串

    var num = 23; typeof(num + '')
    "string"
    var num = 'sg'; typeof(num-0)
    "number"

    写在最后:

    tips:通过对比妙味课堂的视频和网上的一些教程内容(个人博客,阮一峰,司徒正美等)发现都没有全部包含了数据类型转换的所有情况,所有在学习JS的时候,还需要自己多看,多动手,这样才更加准确和深刻理解。

  • 相关阅读:
    机器学习--决策树
    插入排序、选择排序的实现与性能比较
    【笔记】如何实现属性可修改的函数装饰器
    【笔记】如何为被装饰的函数保存元数据
    【笔记】对文件的一些操作
    【笔记】对字符串的一些操作
    USB鼠标按键驱动
    LCD驱动 15-3
    LCD驱动 15 -2
    LCD驱动 15-1
  • 原文地址:https://www.cnblogs.com/zhangxg/p/4550658.html
Copyright © 2011-2022 走看看