JS类型转换

值类型转换
定义:类型转换分为显式转换和隐式转换。区别在于,显式类型转换发生在静态类型语言的编译阶段,隐式类型转换发生在动态类型语言的运行时。

    var a = 42;
    var b = a + ""; //隐式
    var c = String(a); //显式

抽象值操作
定义:ES5规范中定义了一些抽象操作(即仅供对内部使用的操作)和转换规则。

toString
对于普通对象来说,除非自行定义,不然toString都会返回内部属性[[Class]]的值,如"[object object]"。注意:数组默认的toStirng方法经过重新定义。
    var a = [1, 2, 3];
    a.toString();//"1,2,3"

    JSON字符串化
    常用工具类函数JSON.stringify()在序列化JSON对象时也会调用toString。

    JSON.stringify(24); //"24"
    JSON.stringify("24"); //""24""
    JSON.stringify(null); //"null"
    JSON.stringify(true); //"true"

    //不安全的JSON值
    JSON.stringify(undefined);//"undefined"
    JSON.stringify(function(){}); //"undefined"
    JSON.stringify([1,undefined,function(){},4]); //"[1,null,null,4]"
    JSON.stringify({a:24,b:function(){}}); //"{a:24}"
//对于循环引用的对象会报错
//如果需要对含有非法JSON值的对象序列化,可以手动定义对象的toJSON方法,然后使用它返回安全的值进行序列化。
    var o = {};

    var a = {
       n:8,
       o:o,
       f:function(){}
    }

    //建立循环引用
    o.e = a;
    JSON.stringify(a); //error

    //定义toJSON方法
    a.toJSON = function(val){
        return this.n
    }
    //toJSON返回的是一个能够被序列化的安全JSON值。
    JSON.stringify(a); //"{n:8}"

    //JSON.stringify的可选参数(JSON_Obj,keys_Array 或者 Callback, tab_space)
    //space为每一级缩进的字符数
    //callback第一次调用时,k为undefined
    var a = {
        b:24,
        c:"8",
        d:[1,2,3]
    };

    JSON.stringify(a,["b","c"]) //"{"b":24,"c":"8"}"

    JSON.stringify(a,function(k,v){
        if(k !== c){
            return v;
        }
    }) //"{"b":24,"c":"8"}"
toNumber
为了将值类型转换为相应的基本类型值,操作操作会首先检查该值是否具有valueOf方法,如果有则返回基本类型值,就使用该值进行强制类型转换。如果没有则调用toStirng方法的返回值进行强制类型转换。若valueOf和toString()均无返回值,则报错。
    var a = {
        valueOf:function(){
            return "24";
        }
    }
    //"24"
    var b = {
        toString:function(){
            return "24";
        }
    }
     //"24"
    var c = [4, 2];
    c.toString = function(){
        return this.join("");
    }
     //"24"
    Number(a);
    Number(b);
    Number(c);
toBoolean
假值:undefined、null、false、+0、-0和NaN、""
假值的布尔强制类型转换结果为false,其他为真值,转换结果为true。
注意:被包装器函数封装的假值转换结果为true。
    var a = new Boolean(false); //true
    var b = new Number(0);  //true
    var c = new String(""); //true

字符串和数字之间的显示转换

    //通过String()和Number()来实现
    var a = 42;
    var b = String(a); //"42"

    var c = "24"; 
    var d = Number(c); //24

    //其他方式
    var e = a.toString(); //"42"
    var f = +c;  //24
    //~运算符 (字位操作符“非”)
    //位操作符只适用于32位整数,运算符会强制操作数使用32位格式。通过toInt32抽象操作实现。

    var a = "hello world";
    ~a.indexOf("hello"); //-1 真值
    ~a.indexOf("abc"); //0 假值

    //~~将值截取位32整数

    var a = 39.6;
    var b = -39.6;
    var c = 39.4;
    var d = -39.4;

    ~~a; //39
    ~~b; //-39
    ~~c; //39
    ~~d; //-39

    //显示解析字符串
    var a = "24";
    var b = "24px";

    Number(a)//24
    parseInt(a)//24

    Number(b) //NaN
    parseInt(b) //24

    //parseInt针对的是字符串,对于非字符参数会强制转化为字符串类型,parseInt的第二个参数
    //来指定转换的基数,若没有传入第二个参数,则根据第一个参数的第一个字符来决定
    //若第一个字符为x或X,则转换为16进制数字,0为八进制。
    //parseInt解析参数,当解析到第一个不为数字的有效字符时结束,如下。
    parseInt(Infinity); //NaN
    parseInt(Infinity,19); //18 I以19为基数时,值为18

    //显示转化为Boolean类型值
    //使用!!或者Boolean

    //隐式强制类型转换
    //字符串和数字 :数字 => 字符串
    var a = 24;
    var b = "8";
    a + b //"248"

    //数组用"+"号运算,强制转化成字符串
    var c = [1, 2];
    var d = [3, 4];
    c + d //"1,23,4"

    //字符串的隐式转换,会先调用该对象的抽象操作valueOf获取值,然后通过toString方法返回该值的字符串形式。

    var foo = {
        valueOf:function(){
            return 24;
        },
        toString:function(){
            return 8
        }
    }

    //隐式转换
    a + "" // "24"
    //显示转换
    String(foo) //8 

    //字符串转数字
    var a = "24";
    a - 0 //24

    var c = [1];
    var b = [2];
    c - b //-1


    //布尔值和数字

    var a = [true,false,true];
    var sum = 0;

    for(var i = 0, length = a.length; i < length; i++){
        //隐式转换
        if(a[i]){
            //do sth
            sum += a[i];
        }
        //显示转换
        sum += Number(!!a[i]);
    }

    && 和 ||
    &&连接的值,若都为真,则返回最后一个操作数
    ||连接的值,返回第一个为真的操作数

    //符号类型的强制类型转换
    var s = Symbol("FZW");
    String(s); //Symbol("FZW") node 6.9+
    s + "" //Cannot convert a Symbol value to a string

    //== 和 === 
    //误区:==检查值是否相等,===检查值和类型是否相等
    //== 和 === 的速度差可以忽略不计

    //正解:==和===检查操作数是否相等时,都会去检查操作数的类型,区别在于操作数类型不同时,它们的处理方式不同。

    //ES5抽象操作方法定义了 == 的行为
    //如果两个值类型相同,就仅比较两者是否相等,反之发生隐式强制类型转换在做比较
    //特殊情况:NaN !== NaN //true  +0 == -0 //true

    //==隐式强制类型转换规则
    //字符串和数字比较

    var a = 24;
    var b = "24";
    a == b //true
    a === b //false

    //如果Type(a)为数字,Type(b)为字符串,则返回a == ToNumber(b)的结果
    //如果Type(a)为字符串,Type(b)为数字,则返回ToNumber(a) == b的结果


    //其他类型和布尔类型之间的比较
    var a = "24";
    var b = true;
    a == b //false

    //如果Type(a)为布尔类型,则返回ToNumber(a) == b的结果
    //如果Type(b)为布尔类型,则返回a == ToNumber(b)的结果

    上诉比较实际转化为:"24" == 1 //false
    同理 a == false //false ,实际转为 "24" == 0 //false

    建议:无论什么情况都不要使用 n == true/false 的比较方式

    //undefined 和 null的比较
    // undefined == null //true
    // undefined === null //false
    //设计null和undefined的判断
    if(a == null){
        //do sth
    }

    //对象和非对象之间的比较
    //如果Type(a)为数字或字符串,Type(b)为对象,则返回a == toPrimitive(b)的结果
    //如果Type(b)为对象,Type(b)为数字或字符串,则返回toPrimitive(a) == b的结果

    var a = [24];
    var b = 24;
    a == b //true

    var c = "fzw";
    var d = String(c);
    c == d //true

    //假值比较
    "0" == null         //false
    "0" == undefined    //false
    "0" == false        //true 
    "0" == NaN          //false
    "0" == ""           //false

    false == null       //false
    false == undefined  //false
    false == NaN        //false
    false == 0          //true
    false == ""         //true
    false == []         //true
    false == {}         //false

    "" == null          //false
    "" == undefined     //false
    "" == NaN           //false
    "" == 0             //true
    "" == []            //true
    "" == {}            //false

    0 == null           //false 
    0 == undefined      //false 
    0 == NaN            //false 
    0 == []             //true
    0 == {}             //false

    //极端情况
    [] == ![] //true
    ![]通过隐式类型转化,[] == false ,在转化为 [] == 0,
    再转化为,"" == 0 , 最后转化为 0 == 0 ,输出true

    //抽象关系比较
    // var a = [42];
    // var b = ["43"];
    // console.log(a > b); //false
    // console.log(a < b); //true


    var a = ["043"];
    var b = [42];
    console.log(a > b); //false
    //a和b并没有被转化成数字,而是转化为"043"和"42"两个字符串进行比较,它们分别以"0"和"4",因为"0"在字母顺序上小于"4",所以最后结果返回为false.

    var c = {a:24};
    var b = {b:23};

    a < b  //false
    a > b  //false
    a == b //false

    a <= b //true
    b >= a //true
在JS中,“<=”不是小于或者等于的意思,而是不大于。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值