javascript 类型转换

  JavaScript任何时候都可以为变量赋值(数字、字符串等),不过如果我让两个变量相加,其中一个是数字,另一个是字符串,会发生什么呢?

  JavaScript很聪明,它会尝试根据你的需要转换类型。例如,如果你将一个字符串和一个数字相加,它就会把这个数字转换为一个字符串,然后将两个字符串串联起来。这就是这篇文章要讲的JavaScript类型转换,

介绍:

   JavaScript中变量可以分配到Reference value或者Primitive Value。Reference value也称为对象,存储在堆中,Reference value的变量指向对象在内存中的地址。Primitive Value包含Undefined、Null、Boolean、Number、String。Reference Value包括function、array、regex、date等。

  我们可以使用typeof来确定JavaScript变量的数据类型。

typeof null;  // "object"
typeof undefined;  // "undefined"
typeof 0; // "number"
typeof NaN; // "number"
typeof true; // "boolean"
typeof "foo"; //"string"
typeof {}; // "object"
typeof function (){}; // "function"
typeof []; "object"

1. 转换成Boolean

  使用Boolean()函数,可以将任意类型的变量强制转换成布尔值。还有当JavaScript遇到预期为布尔值的地方(比如if语句的条件部分,a ==(>或者<) b的比较运算,a &&b(a||b或!a)的逻辑运算),就会将非布尔值的参数自动转换为布尔值。

  Primitive Value除了undefinednull""(空字符串)0-0NaN转换为false,其他的均转换为true。

undefined null true false ""(空字符串) "1.2" "one" 0 -0 NaN Infinity -Infinity 1(其他非无穷大的数字) {} [] [9] ['a'] function(){}
布尔值 false false true true false true true false false false true true true true true true
true true

 

Boolean(undefined);    //false
Boolean(null);    //false
Boolean("");   //false
Boolean("1.2")  //true
Boolean(0)   //false
Boolean(-0)   //false
Boolean(NaN)  //false
Boolean(Infinity)  //true
Boolean(-Infinity)   //true
Boolean(1)   //true
Boolean({})   //true
Boolean([])   //true
Boolean([9])  //true
Boolean('a')   //true
Boolean(function(){})   //true

  任何Reference value(对象)的布尔值都是true。甚至值为false、undefined或者null的Boolean对象,其值都为true。

Boolean(new Boolean(undefined))   //true
Boolean(new Boolean(null))   //true
Boolean(new Boolean(false))   //true

在条件语句中,这些Boolean对象都将作为true来判断。例如,下面的条件语句中,if就将对象x看作是true:

var x = new Boolean(false);
if(x){
    //  ...这里的代码仍会被执行
}

 

2. 转换成Number

  数值转换主要发生在以下三种情况:

  1. 使用Number()函数强制转换。

  2. 需要数字的函数中。

    比如:Math.sin(val), isNaN(val), val+1, val-1, val/1等四则运算中,还包括+val, -val等运算中。

  3. 比较运算中。

    比如:'00100' > 1  //false,而 '00100' > '1'  //true

  使用Number()函数

undefined null true false ""(空字符串) "1.2" "123e-2"  "010"  "0x10"  "0xff"  "-010"  "-0x10"  "one" 0 -0 NaN Infinity -Infinity 1(其他非无穷大的数字) {} [] [9] ['a'] function(){}  
数字 NaN 0 1 0 0 1.2  1.23  10  16  255  -10  NaN NaN 0 -0 NaN Infinity -Infinity 1 待讨论 0 9 NaN NaN  

Primitive Value转换成数值具有以下规则:

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

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

  3. 布尔值:true转成1,false转成0.

  4. undefined: 转成NaN。

  5. null: 转成0.

  6. Number函数会自动过滤一个字符串前导和后缀的空格

[0] == 0   //true
"\n0\n" == 0  //true
"\n0\n" == false  //true

 

Object转换成数值相对比较复杂些,Object转换成数值的算法如下:

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

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

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

example:

  1. 自定义valueOf。

var stu = {
    age: 18, 
    valueOf: function(){
        return this.age
    }
};

console.log(+stu)   //18

  2. 如果与自定义toString,但是没有valueOf,解析器会使用toString来数值转换:

var stu = {
    age: 18, 
    toString: function(){
        return this.age
    }
};

console.log(+stu)   //18

  3. 如果valueOf和toString返回的均不是原始值,则报错。

var stu = {
    age: 18, 
    valueOf: function(){
        return {}
    }, 
    toString: function(){
        return {}
    }
} 
console.log(+stu)
//Error:  Uncaught TypeError: Cannot convert object to primitive value

3. 转换成String

  字符串转换主要发生在以下两种情况:

  1. 使用String()函数强制转换。

  2. 当JavaScript遇到预期为字符串的地方,就会将非字符串的数据自动转为字符串。

    比如:obj + 'string', '0'+0。

使用string()函数:

 

undefined null true false ""(空字符串) "1.2" "one" 0 -0 NaN Infinity -Infinity 1(其他非无穷大的数字) {} [] [9] ['a'] function(){}  
数字 "undefined" "null" "true" "false" "" "1.2" "one" "0" "0" "NaN" "Infinity" "-Infinity" "1" 待讨论 "" "9" 使用join()翻番连接各个元素,分隔符为逗号 待讨论  

 

对象类型转换字符串类型步骤如下:

  1. 如果对象有toString方法,就调用toString方法,如果返回的是一个原始类型,把这个原始类型转换成字符串(当然如果toString返回的就是字符串就不需要了)
  2. 如果对象没有toString方法,或者toString返回的不是原始类型,就尝试调用valueOf方法,如果valueOf方法返回的是原始类型,则将原始类型转换成字符串(如果valueOf放回的就是字符串就不需要了)
  3. 如果toString方法和valueOf方法都不存在,或者他们的返回类型都不是原始类型,则抛出TypeError异常

example:

  1. 自定义toString。

var stu = {

    toString: function(){
        return "beauty"
    }
};

String(stu)  //beauty

  2.自定义valueOf

var stu = {

   valueOf: function(){
        return "student"
    }
};

String(stu)  //"[object Object]"

  3. 自定义toString和valueOf

var stu = {   
valueOf: function(){
        return "student"
    },

toString:
function(){ return "beauty" } }; console.log(String(stu)) //“beauty”

  4. toString和valueOf均不是原始值,则报错

var stu = {   
    valueOf: function(){
        return {};
    },

    toString: function(){
        return {}
    }
};

console.log(String(stu))
//Uncaught TypeError: Cannot convert object to primitive value

  特例情况:+operator

  先看下面的例子:

var stu = {
    toString: function(){
        return "student";
    },
    valueOf: function(){
        return 18;
    }
};
stu + "foo"  //"18foo"
[stu, "foo"].join(""); //studentfoo

  在这个例子中,我们使用+操作符来座字符串连接,但是stu没有使用toString转换成"student",而是使用valueOf转换成数字18.然后与"foo"连接成"18foo"。结果不是我们预期的,但是它是怎么实现的?我们再看下一个例子。

var date1 = new Date();
date1.toString=function(){return "now";};
date1.valueOf=function(){return "wait";};
date1+"foo"   //"nowfoo"
[date1+"foo"].join("");   //"nowfoo"

  在这个例子中,我们使用+操作符来作字符串连接,使用toString(),得到字符串"now".然后与"foo"连接成"nowfoo"。结果是我们预期的。

  对于非日期型的对象,转换过程是先使用对象的valueOf()方法,如果返回的不是原始值或者valueOf不存在,那就会再调用toString()方法,如果返回的仍然不是原始值,那就会抛出类型错误的异常。而对于日期型的对象,它首先会使用toString()然后才是valueOf()。

 

参考文章:

阮一峰:数据类型转换

 MDN: Boolean

posted on 2014-12-08 21:07  加油_linda  阅读(200)  评论(0编辑  收藏  举报