JS中的数据类型转换

ES5中一共有6种数据类型,其中5种基本类型(String、Number、Boolean、Null、Undefined),1种引用类型(Object)。基本类型值可以相互换转换,并且引用类型值也可以通过某种方式转换成基本类型值。

引用类型值转换为基本类型值的方法有两个,分别是 valueOf方法和toString方法。

强制转换为基本类型值可以使用各自的函数 String,Boolean, Number。

转换为String

类型 strting值
String “a” “a”
Number 1 “1”
Boolean true “true”
Boolean false “false”
Null null “null”
Undefined undefined “undefined”
Object {} {}.toString()

普通对象Object转换为String,如果Object没有自定义toString方法则默认返回对象的[[class]]属性,如题如下:

1.自定义对象具有toString方法

var a = {
    toString: function(){
        return '我是toString的返回值';
    }
};
String(a); //我是toString的返回值

2.自定义对象并不具有toString方法

var a = {};
String(a); // [object Object]

var b = [];
String(b); // "" 数组有自定义的toString方法 将数组元素用 , 拼接成字符串并返回

注:Number转换为String稍微有点特殊,如果数字过大或者过小则用指数表示。

转换为Number

类型 Number值
Number 1 1
String “” 0
String “1” 1
String “1a” NaN(数字的一种,意思是Not a Number)
Boolean true 1
Boolean false 0
Null null 0
Undefined undefined NaN
Object {} 调用 valueOf() 或者 toString()

对象转为Number类型步骤:

  1. 调用对象的 valueOf 方法(如果有该方法),检查返回值
  2. 如果valueOf返回值是基本类型则转为Number
  3. 如果valueOf返回值不是基本类型则调用toString
  4. 如果toString返回值是基本类型则转为Number
  5. 如果toString返回值也不是基本类型则报错

1.具有valueOf方法和toString方法的对象

var a = {
    valueOf: function(){
        return 1;
    },
    toString: function(){
        return '2';
    }
}
Number(a); // 1

2.只具有toString方法的对象

var a = {
    toString: function(){
        return '2';
    }
}
Number(a); //2  这个 2 是数字并不是字符串

3.具有返回引用类型值得valueOf方法和toString方法

var a = {
    valueOf: function(){
        return {};
    },
    toString: function(){
        return {};
    }
}
Number(a); //TypeError 错误

转换为Boolean

在JS中所有值可以分为两类真值假值,对象(引用类型)一般都是真值。

类型 Boolean类型
Boolean true true
Boolean false false
String “1” true
String “” false
Number 0 false
Number 1 true
Number NaN false
Object {} true

隐式强制类型转换

在JS中有很多的隐式强制类型转换,在一些并不明显的地方发生了强制类型转换,例如加法运算符(+),减法运算符(-),逻辑运算符 && 和 ||等。

符号 + 中出现的隐式强制类型转换

加法运算符既可以用作字符串的拼接,也可以用作数字的相加。

加法运算符的两个操作数只要有一个是字符串则执行字符串的拼接,否则执行数字的相加。

var a = '1' + 1;
console.log(a); // '11'

var b = 1 + 1;
console.log(2); // 2

加法运算符的两个操作数中如果有对象则遵循以下步骤:

  1. 调用 valueOf 方法,如果返回值是基本值则依据第一条继续执行相加操作

  2. 如果返回值不是基本值则调用 toString 方法,如果返回值是基本值则依据第1条继续执行相加操作

  3. 如果 toString 也不返回基本值则报错

// 1. 应该是首先调用valueOf方法,并且对于返回的基本类型值不会toNumber
var a = {
    valueOf: function(){
        return '1';
    },
    toString: function(){
        return 1;
    }
};

console.log(a + 1); // '11'

// 2. 如果valueOf返回的不是基本类型值则调用toString
var b = {
    valueOf: function(){
        return {};
    },
    toString: function(){
        return '1';
    }
};

console.log(b + 1); // '11'

// 3. 如果两个方法都不返回基本类型值则报错
var c = {
    valueOf: function(){
        return {};
    },
    toString: function(){
        return {};
    }
};

console.log(c + 1); TypeError 报错了

如果操作数中有Boolean,依据另一个操作数的类型来强制类型转换

  1. 另一个操作数是String则将Boolean转换为String,依据转换为String规则

  2. 另一个操作数是Number则将Boolean转换为Number,依据转换为Number规则

var a = 1 + true; 
console.log(a); // 2

var b = 1 + false;
console.log(b); // 1

var c = '1' + true; // '1true'
console.log(c); // '1true'

var d = '1' + false;
console.log(d);  // '1false'

根据以上规则经常看到的 a + '' 就不难理解了,就是要将a转换为字符串。但是要注意的是a如果是对象的话和直接调用String(a)的结果在特定情况下还是有区别的。区别在于String方法并不会调用valueOf方法(但是正常情况下并不会自定义对象的valueOf方法)。

算术运算符中除了 + 以外的其他运算符都会将两个操作数依据转换为Number规则换为Number,然后在进行操作。

关于 [] + {} 和 {} + [] 得到结果不一样的解释

[] + {}; // 控制台中结果是 "[object Object]"

{} + []; // 控制台中结果是 数字0

[]转为基本类型值为 “” 空子符串,{}转为基本类型值为”[object Object]”则得到结果”[object Object]”

JS中以大括号开头会被当做代码块,{} + [] 解释为 +[]则得到了0

到Boolean类型值的隐式强制类型转换

在以下语句和表达式中需要Boolean类型值的地方都会出现依据转为Boolean规则向Boolean类型值转换:

  1. if( … )
  2. for( …; …; … ) 括号中第二个表达式
  3. while( … ) 和 do…while( … )
  4. … ? … : …
  5. 逻辑运算符 && 和 || 的左操作数(为什么是左操作数?右边为什么没有变成Boolean类型值?)
  6. ! 取反

宽松等于(==)中的隐式强制类型转换

在JS中宽松等于有很多让人捉摸不透的地方例如 [] == false 返回的是true,但是 [] 显然并不是假值但是却相等,[]==![] 你猜的没错这个也返回true,"0"==false 你又才对了这个返回的还是true,我想说的是”0”并不是假值但是为什么还会返回true呢???

详情请看 JS中令人捉摸不透的宽松等于

参考:
你不知道的javascript中卷

猜你喜欢

转载自blog.csdn.net/lettertiger/article/details/79433906