Javascript数据类型的相互转换详解

244 1 年前
JavaScript 是一种动态类型语言,变量没有类型限制,但是各种运算符对数据类型是有要求的。如果运算符发现,运算子的类型与预期不符,就会自动转换类型。比如,减法运算符预期左右两侧的运算子应该是数值,如果不是,就会自动将它们转为数值。

其他数据类型转换为布尔类型 Boolean

转换为布尔类型的场景:

  • Boolean()转换函数
  • ! 取反 -!! 取反再取反
  • 在条件判断的时候

可以对任何数据类型的值调用 Boolean()函数,总会返回一个Boolean 值

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ""(空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined n/a① undefined

n/a(或 N/A),是 not applicable 的缩写,意思是“不适用”。

从上面表格可以看出,只有 0NaN空字符串undefinednull转换成 Boolean 值时为 false,其余都转换为 true

//对象和对象:比较的是空间地址
[] == [] -> false

//对象和数字:把对象转换成数字
[] == 0 -> true
({}) == NaN  -> false 
//Number({}) ==> Number("[object Objict]") ==> NaN,但是NaN和自己都不相等。

//对象和字符串:把两边都转换成数字然后进行比较
[ ] == "" -> true

//对象和布尔:把两边都转换成数字然后进行比较
[ ] == true ->false //0 == 1 所以不相等
[ ] == false -> true //0 == 0
![ ] == false -> true //两个布尔比较了 false == false

//对象除了和对象比较,都转换成数字再比较

//字符串和数字:字符串转换成数字

//字符串和布尔:都转换成数字
...

//规律:两个等号比较,左右两边数据值类型不一样的话,浏览器会把两边的类型都转换为数字(Number方法)然后再比较,null和undefined除外

null == undefined -> true
null === undefined -> false
null以及undefined和其它任何值都不相等

其它数据类型转换成Number类型

转换为Number类型的场景:

  • isNaN()
  • Number()
  • parseInt()
  • parseFloat()
  • 在进行加减乘除数学运算的时候,

有 3 个函数可以把非数值转换为数值:Number()parseInt()parseFloat()Number()可用于任何数据转Number,而另两个函数则专门用于把字符串转换成数值。

Number()函数转换规则如下:

  • Boolean 值true 和 false 将分别被转换为 1 和 0。
  • 如果是数字值,只是简单的传入和返回
  • null ,转换为 0。
  • undefined 转换为 NaN。
  • 字符串转换的情况
    • 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1"会变成 1,"123"会变成 123,而"011"会变成 11(注意:前导的零被忽略了);
    • 如果字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽略前导零);
    • 如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整数值;
    • 如果字符串是空的(不包含任何字符),则将其转换为 0;
    • 如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。
  • 对象转换的情况,包含单个数值的数组返回这个数值,空数组返回0,其余其余规则见下面所述。
var num1 = Number("Hello world!"); //NaN
var num2 = Number(""); //0
var num3 = Number("000011"); //11
var num4 = Number(true); //1
true -> 1  false -> 0
"" -> 0  "12" -> 12  "12px" -> NaN
null -> 0
undefined -> NaN
[] -> 0
[12] -> 12
{} 、 /^$/ 、 function(){} -> NaN

Number方法的参数是对象时转换规则比较复杂

  • 第一步,调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。
  • 第二步,如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。
  • 第三步,如果toString方法返回的是对象,就报错。
var obj = {x: 1};
Number(obj) // NaN

// 等同于
if (typeof obj.valueOf() === 'object') {
  Number(obj.toString());
} else {
  Number(obj.valueOf());
}

上面代码首先调用obj.valueOf方法, 结果返回对象本身;于是,继续调用obj.toString方法,这时返回字符串[object Object],对这个字符串使用Number函数,得到NaN。Number({}) // NaN

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

Number(obj)
// TypeError: Cannot convert object to primitive value

Number({
  valueOf: function () {
    return 2;
  }
})
// 2

Number({
  toString: function () {
    return 3;
  }
})
// 3

Number({
  valueOf: function () {
    return 2;
  },
  toString: function () {
    return 3;
  }
})
// 2

parseInt()函数转换规则如下:

  • parseInt()函数在转换字符串时会忽略字符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者负号,parseInt() 就会返回 NaN;
  • 如果第一个字符是数字字符parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。例如,"1234blue"会被转换为 1234,因为"blue"会被完全忽略。类似地,"22.5"会被转换为 22,因为小数点并不是有效的数字字符。
  • 如果字符串中的第一个字符是数字字符,parseInt()也能够识别出各种整数格式
var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(""); // NaN
var num3 = parseInt("0xA"); // 10(十六进制数)
var num4 = parseInt(22.5); // 22
var num5 = parseInt("070"); // 56(八进制数)
var num6 = parseInt("70"); // 70(十进制数)
var num7 = parseInt("0xf"); // 15(十六进制数)

parseInt()函数提供第二个参数:转换 时使用的基数(即多少进制)。

var num1 = parseInt("AF", 16); //175
var num2 = parseInt("AF"); //NaN
var num1 = parseInt("10", 2); //2 (按二进制解析)
var num2 = parseInt("10", 8); //8 (按八进制解析)
var num3 = parseInt("10", 10); //10 (按十进制解析)
var num4 = parseInt("10", 16); //16 (按十六进制解析)

parseFloat()函数转换规则如下:

  • parseFloat()类似parseInt(),从第一个字符(位置 0)开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。
  • 字符串中的第一个小数点是有效的,而第二个小数点就是无效的了
  • parseFloat()只解析十进制值
var num1 = parseFloat("1234blue"); //1234 (整数)
var num2 = parseFloat("0xA"); //0
var num3 = parseFloat("22.5"); //22.5
var num4 = parseFloat("22.34.5"); //22.34
var num5 = parseFloat("0908.5"); //908.5
var num6 = parseFloat("3.125e7"); //31250000 

isNaN()

用来判断一个值是否为NaN。但是 isNaN只对数值有效,如果传入其他值,会被先转成数值。

isNaN('Hello') // true
// 相当于
isNaN(Number('Hello')) // true

isNaN({}) // true
//相当于
isNaN(Number({})) // true

isNaN(['xzy']) // true
// 等同于
isNaN(Number(['xzy'])) // true

对于空数组和只有一个数值成员的数组,isNaN返回false

isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false

正确判断NaN的方法

//NaN本身就是数字
function myIsNaN(value) { 
      return typeof value === 'number' && isNaN(value);
 }
//NaN不等于NaN
function myIsNaN(value) { 
  return value !== value;
}

Javasctip中的数学运算

Javasctip中的数学运算有 +,-,*,/ ,除了加法( + )有特殊性,其余的运算符都是数学运算,也就是遇到非数字类型,需要把其转换为 Number 再进行运算。

加法的特殊性:在遇到字符串的时候, + 不是数学运算,是字符串拼接,只要不遇到字符串就是数学运算

1-"1" -> 0
10*null -> 0
10/undefined -> NaN  //Number(undefined)==>NaN
10*[10] -> 100

1+"1" -> "11"
null+"1" -> null1

其他数据类型转换为字符串 String

  • toString()方法转换
  • String()转型函数

toString()方法

  • 数值、布尔值、对象和字符串值都有 toString()方法。但 null 和 undefined 值没有这个方法。
  • 数值的 toString()方法可以传递一个参数:输出数值的基数,默认以十进制格式
var age = 11;
var ageAsString = age.toString(); // 字符串"11"
var found = true;
var foundAsString = found.toString(); // 字符串"true"

var num = 10;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // "10"
alert(num.toString(16)); // "a" 

在不知道要转换的值是不是 null 或 undefined 的情况下,还可以使用转型函数 String()

String()转型函数

将任何类型的值转换为字符串,规则如下:

  • 如果值有 toString()方法,则调用该方法并返回相应的结果;
  • 如果值是 null,则返回"null";
  • 如果值是 undefined,则返回"undefined"。
var value1 = 10;
var value2 = true;
var value3 = null;
var value4;
alert(String(value1)); // "10"
alert(String(value2)); // "true"
alert(String(value3)); // "null"
alert(String(value4)); // "undefined" 

字符串拼接是把其他的值转换成字符串然后再拼接(toString)

其它的数据类型的toString是直接把值用单(双)引号包起来即可,只有对象的有特殊性,对象.toString() === "[object Object]"

分类栏目
© 2018邮箱:11407215#qq.comGitHub沪ICP备12039518号-6