JS为什么有数据类型转换?
因为JS是一门动态语言,变量没有类型限制?变量的值随时都可以赋予任何值。 这也意味着,JS引擎没有办法在编译的时候确定变量的数据类型,必须得到运行的时候才能根据值来确认数据的类型。但是各种运算符对数据类型是有要求的,如果运算符发现运算子的数据类型和预期的不符,就会自动类型转换。
数据类型的转换方式有2种
1、强制转换;2、隐式转换。
强制转换:
所谓的强制转换,是需要程序员手动调用:Number()、String()、Boolean()这个3个函数,将数据转换成对应的值。
数值类型转换和判断方法
1、原始值的转换规则:
Number() 函数的转换规则:只有参数是纯数字和布尔值,才能转成数值,否则全部转成NAN。除了Number(null)的是特殊情况值为0。 代码如下:
function primitiveToNumber(arg) {
if (arg === null || arg === false) {
return 0
}
if (arg === true) {
return 1
}
let temp = arg + '';
// 由于0~9和小数点的ASCII码范围是46~57,46='.' 47='/'除外
// 小数点的个数
let pointCount = 0
for (var i = 0; i < arg.length; i++) {
let code = arg.charCodeAt(i)
// 判断是不是数字和小数点,如果不是直接返回NaN
if (45 < code && code < 57 && code !== 47) {
// 小数点的个数如果为2的时候直接返回NaN
if (code === 46 && ++pointCount && pointCount === 2) {
return NaN
}
} else {
return NaN
}
}
return arg * 1 //这一步其实也是隐式调用了内置函数Number
}
isNaN() 方法是用来判断参数的值是不是一个数字,如果不是返回true,否则返回false, isNaN方法等价于下面的方法:
function myIsNaN(arg) {
return Number(arg).toString() === 'NaN' ? true :false ;
}
console.log(myIsNaN(null))//false
//因为Number(null)的值为0,所以myIsNaN输出肯定是false
parseInt() 方法接受2个参数,第二参数是转换进制,默认是10进制。就以默认的10进制为基础,总结一下转的规则:从参数的首位取出数字直到取出的不是数字就返回结果,如果首位不是数子则返回NaN,否则返回数值。除
2、引用类型转换格则:
除了Number([813])的值为813,数组有一个元素,且元素一定是数值类型或者null,其他的都是NAN,Number()对引用类的处理过程如下:
1、调用对象的valueOf方法,如果返回的原始值,就直接调用Number函数返回该值。
2、如果对象的valueOf方法的返回值不是原始值,
2-1:判断对象的valueOf方法的值,如果是数组且长度为1且存的值为数值,就直接返回该数组下标为0的值。
2-2:如果toString返回的不是一个对像,则调用toString方法返回的结果进行Number函数转换
2-3:否则报类型错误:不能将对象转换成原始值,实现的代码如下:
function myNumber(arg) {
// 判断参数的数据类型是不是原始值 或者参数为null
if(typeof(arg)!=='object'||arg===null){
return primitiveToNumber(arg)
}
let myValueOf = arg.valueOf();
if (typeof(myValueOf) !== 'object') {
return primitiveToNumber(myValueOf)
} else {
//判断valueOh数返回的是不是数组,而且长度为1,且元素的值为数字或者为null
if (myValueOf instanceof Array &&
myValueOf.length === 1 &&
(typeof(myValueOf[0]) === 'number' || myValueOf[0] === null)) {
return primitiveToNumber(myValueOf[0]);
} else if (typeof(arg.toString()) !== 'object') {
return primitiveToNumber(arg.toString())
}
throw 'Uncaught TypeError: Cannot convert object to primitive value';
}
}
}
验证2-3的代码的代码如下:
var obj = {
valueOf: function() {
console.log("调用了valueOf");
return {}
},
toString: function() {
console.log("调用了toString");
return {}
}
}
//Number(obj);
//myNumber(obj);
String()函数的转换规则:
1、如果是原始值直接返回 参数+''
2、如果参数是对象则返回类型字符串,如果是数组就返回数组中元素的字符串,调用的过程是与Number()的调用过程的第一步和第二换掉了,也就是先调用toString(),在调用valueOf();代码如下:
function myString(arg) {
if (typeof(arg) !== 'object'||arg===null) {
return arg + ""
}
let str = arg.toString()
if (typeof(str) === 'string') {
return str
} else {
let toValue = arg.valueOf()
if (typeof(toValue) === 'object') {
throw 'Uncaught TypeError: Cannot convert object to primitive value';
}
return toValue
}
}
验证代码如下:
console.log(String(null),myString(null));
console.log(String(undefined),myString(undefined));
console.log(String(NaN),myString(NaN));
console.log(String(1),myString(1));
console.log(String('a'),myString('a'));
console.log(String(true),myString(true));
var obj = {
valueOf: function() {
console.log("调用了valueOf");
return {}
},
toString: function() {
console.log("调用了toString");
return {}
}
}
//toString(obj);
//myString(obj);
注:typeOf的返回值有6种情况:number、string boolean、object、undefined、function,typeOf(null)是object,Number(null)是0
Boolean()函数的转换规则: 除了这6个值:''、0、 false、 NaN、 null、 undefined返回false。其他值返回true,代码如如下:
function myBoolean(arg) {
switch (arg+'') {
case '':
case '0':
case 'false':
case 'null':
case 'NaN':
case 'undefined':
return false
default:
return true
}
}
隐式类型转换:隐式转换的过程是:JS引擎根据运算符期望运算子的数据类型自动调了,需要转换的对应类型方法:String()、Number()、Boolean(),这个过程对程序员不可见。
非严格相等
==操作符对于不同类型的值,进行的比较如下图所示:
developer.mozilla.org/zh-CN/docs/…
隐式转换的优先级:number,object,string,boolean
1、number:无论是谁遇到我,你们都要隐式转换;
2、boolean:我无论遇到谁,都有变成number;
3、object:我无论遇到谁,都有变成primitive;
总结
1、undefined==null//true,除了这个情况他们不等于任何值。
2、 NaN不等任何值包括自己都不等。
3、数值转换:
3-1:原始值除了纯数字、小数 、null、true、false。其他的全部转NaN。
3-2:引用类型除了[纯数字 / 小数]或者**[]**。其他的全部转为NaN
4、字符串
4-1:原始值总是返回自己本身的值+""
4-2:引用值总是返回 [ object Object ]
5、布尔值:除了 0 、'' 、false、 null、 undefined、 NaN这个6个值返回false,其他的全部返回true
6、typeof函数 总是返回以下6个值:number 、string 、boolean 、object 、function、undefined