js类型转换大全

4 篇文章 0 订阅

概要

JavaScript是一种弱类型语言,在定义变量的时候不需要指定变量类型所带来的后果就是:使用的时候,遇到不符合的类型时就会触发隐式类型转换,稍不注意,就会得到预期之外的结果。所以这篇文章的目的为了更好的避免出错和巧妙的利用js变量之间的类型转换。


我们都知道,js的基本数据类型有:

  1. String、基本数据类型
  2. Boolean、基本数据类型
  3. Number、基本数据类型
  4. undefined、基本数据类型
  5. null、基本数据类型
  6. Object、引用数据类型
  7. Symbol(es6新增)、基本数据类型

转换为String

输入类型转换方法结果特例
BooleanBoolean.ptototype.toString()

true  => "true"

false => "false"

Number

Number.prototype.toString(radix=10)

radix是进制数,默认十进制

1.无符号数字,数字加引号变成字符串

2.正号数字,去掉正号,数字部分加引号变成字符串

3.负号数字,保留负号,数字部分加引号变成字符串

12 => "12" ; NaN => "NaN"

var num = -3;num.toString(2) => "-11"

Infinity => "Infinity"

+0 => "0"

-0 => "0"

undefinedString()"undefined"
nullString()"null"
Object

Constructor.prototype.toString()或

Constructor.prototype.valueOf()

参考下面介绍

{} => "[object Object]"

[1,2,3] => "1,2,3"

function(){} => "function(){}"

new Date() => "Thu Jul 18 2019 15:54:16 GMT+0800 (中国标准时间)"

new RegExp(/123/,'ig') => /123/ig

new Error('asd') => "Error: asd"

SymbolSymbol.prototype.toString例如:Symbol('bar').toString() => "Symbol(bar)"

对象的类型转换(String方法)

  • 如果对象有toString方法,则调用之,若该函数返回的是基本数据类型则将值转换为字符串并返回

  • 如果对象无toString方法或调用toString方法返回的并不是基本数据类型,则调用对象的valueOf函数,若该方法存在并返回基本数据则返回该值

  • 以上两个方法都不存在或者都不返回基本数据类型,则会抛出抛出一个 TypeError 异常

  • 以上方法返回的如果是引用类型,并不会递归调用进行转换

测试代码:

var toString = Array.prototype.toString;
var valueOf = Array.prototype.valueOf;
var arr = [1,2,3];
Array.prototype.toString = function(){
    console.log('call array toString');
    return {};
}
Array.prototype.valueOf = function(){
    console.log('call array valueof');
    return 'abc';
};
console.log(String(arr));

//打印结果:
//call array toString
//call array valueof
//abc

js内置对象toString()方法和valueOf()方法返回值:

  • Object对象
  1. toString() => "[object Object]"
  2. valueOf() => 对象本身
var obj = {
    a: 'aa'
};
console.log(obj.toString());//'[object Object]'
console.log(obj.valueOf());//▶{a: 'aa'}
  • Array数组对象
  1. toString() => 调用this.join()并返回
  2. valueOf() => 数组本身
var arr = [1,2,3];
console.log(arr.toString());//"1,2,3"
console.log(arr.valueOf());//▶(3)[1,2,3]
  • Function函数对象
  1. toString() => 返回函数字符串
  2. valueOf => 函数本身
function foo(){}
console.log(foo.toString());//"function foo(){}"
console.log(foo.valueOf());//ƒ foo(){}
  • Date日期对象
  1. toString() => 返回类似Thu Jul 18 2019 21:44:16 GMT+0800 (中国标准时间),这样的字符串
  2. valueOf() => 返回时间戳(精确到毫秒)
var date = new Date();
console.log(date.toString());//"Thu Jul 18 2019 21:44:16 GMT+0800 (中国标准时间)"
console.log(date.valueOf());//1563457456397
  • RegExp正则对象
  1. toString() => 返回正则表达式字面量字符串
  2. valueOf() => 返回正则表达式字面量对象
var reg = new RegExp(/^abc$/,'ig');
console.log(reg.toString());//"/^abc$/gi"
console.log(reg.valueOf());///^abc$/gi
  • Error异常对象
  1. toString() => 返回构造函数名 + 错误字符串 组成的字符串
  2. valueOf() => 返回错误对象本身
var error = new TypeError('aa');
console.log(error.toString());//"TypeError: aa"
console.log(error.valueOf());///TypeError: aa

转换为Boolean

输入类型转换方法结果特例
StringBoolean()非空字符串都是true空字符串("")为false
NumberBoolean()任何非零数字值(包括无穷大)都是true+0、0、-0、NaN均为false
undefinedBoolean()false 
nullBoolean()false 
ObjectBoolean()true 
SymbolBoolean()true 

在进行条件判断的时候,被判断的数据都会被转换为Boolean类型,所以记住上表中的规律适用于绝大部分。

转换为Number

输入类型转换方法结果特例
StringNumber()

字符串中含有非数字类型字符返回NaN,其他直接转换为对应数字

Number('abc') => NaN

Number('123') => 123

Number('123abc') => NaN

1.包含正负号纯数字保留正负号:Number('+123') => 123;Number('-123') => -123

2.包含浮点数则转换为浮点数:Number('-123.45') => -123.45

3.包含十六进制,不含正负号转为10进制:Number('0xff') => 255

4.包含科学计数法转为正常数字:Number("2E4") => 20000;

5.空字符串转为0:: Number('') => 0

BooleanNumber()

true => 1

false => 0

 
undefinedNumber()NaN 
nullNumber()0 
Object

Constructor.prototype.valueOf()或

Constructor.prototype.toString()最后

Number()

参考下面介绍

{} => "[object Object]" => NaN

[] => "" => 0

[1] => "1" => 1

[1,2] => "1,2" => NaN

new Date() => 时间戳

new RegExp(/123abc/,'ig') => "/123abc/id/" => NaN

new Error('abc') => "Error: abc" => NaN 

Symbol无法转换typeError 

对象转换为Number

  • 如果对象有valueOf()方法,则调用之,若该函数返回的是基本数据类型则将值转换数字并返回,基本类型转换为数字遵循上表所述
  • 如果对象无valueOf()方法或调用valueOf()方法返回的并不是基本数据类型,则调用对象的toString()函数,若该方法存在并返回基本数据类型则将其转换为数字并返回
  • 以上两个方法都不存在或者都不返回基本数据类型,则会抛出抛出一个 TypeError 异常

  • 以上方法返回的如果是引用类型,并不会递归调用进行转换

测试代码:

var toString = Array.prototype.toString;
var valueOf = Array.prototype.valueOf;
var arr = [1,2,3];
Array.prototype.toString = function(){
    console.log('call array toString');
    return "123";
}
Array.prototype.valueOf = function(){
    console.log('call array valueof');
    return ['a','b','c'];
};
console.log(+arr);

//打印:
//call array valueof
//call array toString
// 123

其他类型数据转换为null并没有什么意义;

任何类型数据通过void转换结果都是为undefined;

任何类型通过Object()函数,转换的都是对象类型,当然这个也没什么意义

任何类型通过Symbol()函数,转换的都是Symbol类型

隐式类型转换

掌握了不同数据类型之间的相互转换,但是在我们进行运算或者操作的时候,往往会触发隐式类型转换,那么隐式类型转换要遵循什么样的原则呢,之间是否有规律可循?

1."+"运算

加法是一个双目运算符,可以进行加法运算和字符串拼接。如果操作符两边都是数字或者字符串还好说,如果两边不都是数字或者字符串,我们就要进行类型转换。这里我总结一个规律——就是"+"运算类型转换的优先级:

  1. String > Number
  2. null 等于 undefined 等于 Object 等于 Boolean

第一梯队就是String和Number类型且String类型优先级高于Number;第二梯队就是null、undefined、Object及Boolean且优先级相当。进行"+"运算时,运算规则如下:

  1. 从左至右进行分割运算
  2. 优先级低的向优先级高的类型进行转换
  3. 第二梯队中的类型要向第一梯队的类型中进行转换
  4. +"运算符左右都是第二梯队中的类型,优先调用valueOf()方法且返回基本类型则使用,再次调用toString()方法返回基本类型,如果没有或者返回不是基本类型则往Number类型上转。
console.log(1 + false + '2' + null);
//从左至右分割运算
//1 + false => 1; //Number > Boolean
//1 + '2' => '12'; //String > Number
//'12' + null => '12null'; //String > Boolean
var obj = {
    toString(){
        return 'abc'
    },
    valueOf(){
        return 456
    }
};
console.log(obj + true + null + [1] + 1);
//从左至右分割运算
// obj + true => 456 + 1 => 457; //都在第二梯队中,优先转为Number
//457 + null => 457; //Number > null
//457 + [1] => "4571"; //[1].valueOf() => [1];[1].toString() => '1';//String > Number
//"4571" + 1 => "45711";//String > Number

2."=="比较

"=="操作符也是双目操作符,操作符两边如果类型相同则不进行类型转换,直接进行比较,如果类型不相同则要进行转换。

类型相同时

  1. NaN和NaN不等
  2. Object类型比较堆地址({} == {} => false;var a = b = {}; a == b => true)
  3. +0、-0、0相等
  4. 其他都相等

类型不同时

  1. null和undefined相等
  2. Object(Date类型转为String类型)、Number、String、Boolean之间的比较都是返回转换为Number类型进行比较
  3. 其他都不相等(null和undefined与其他类型都不相等)

示例:

console.log([] == ![]);

//左边[]valueOf() => [];调用toString() => '';转换为数字 => 0
//右边![]作为Boolean => false;转换为数字 => 0
//左右相等,返回true

下面介绍一些特例:

console.log({} + 1);
//{} 优先调用valueOf返回{},在调用toString() => "[object Object]"
//"[object Object]" + 1 => "[object Object]1"

但是我们在控制台中直接使用进行运算:

这是因为在控制台中,如果{}前面没有代码的话,会被编译为块级作用域,而不是当做对象来用,所以在控制台中使用{} + 1实际是打印的是 +1 结果。但是在实际代码编写过程中不会出现这种情况。

参考文章

你所忽略的js隐式转换

类型转换与测试

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值