js数据类型的判断与转换
本文最后更新于:2022年5月31日 上午
ECAMScript 中不能自定义数据类型,只能为下列 7 种
简单数据类型(原始类型)
String
Number
NaN
typeof NaN === 'number' 唯一一个自相反的值 NaN !== NaN
Boolean
- 在条件判断时,除了
undefined
,null
,false
,NaN
,''
,0
,-0
,其他所有值都转为 true,包括所有对象。 - 布尔值与其他类型比较都会转为数字
- 在条件判断时,除了
null
typeof null = object
,null 表示一个空对象指针- null 必须手动设置,常用于作为参数传入,说明该参数不是对象
- 设置为 null 的变量或者对象会被内存收集器回收
null
转为数字类型值为0
undefined
- 调用一个值而它本身没有赋值
undefined == null
undefined
转为数字类型为NaN
Symbol
[ES6 新增]- 表示独一无二的值
复杂类型
Object
- 引用类型的值是指向保存在堆中的对象的指针
- 使用时要先从栈中读取内存地址,再沿着指针找到堆中的对象
- Object
- Array
- 数组的每一项可以用来保存任何类型的数据
- Function
- 每个函数都是 Function 的实例
类型判断
typeOf
- 对未声明的变量,只有对它调用
typeof
不报错,returnundefined
- 特殊的几个
typeof undefined; // 'undefined'
typeof Symbol(); // 'symbol'
typeof null; // 'object'
typeof NaN; // number
isNaN
console.log(isNaN(NaN)); //true
console.log(isNaN(10)); //false
console.log(isNaN("10")); //false
console.log(isNaN("blue")); //true
console.log(isNaN(true)); //false
instanceof
instanceof
运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype
属性,但它不能检测null
和 undefined
[] instanceof Array // true
{} instanceof Object // true
new Date() instanceof Date // true
new RegExp() instanceof RegExp // true
null instanceof null // error
undefined instanceof undefined // error
constructor
const arr = [];
const obj = {};
console.log(arr.constructor); // [Function: Array]
console.log(obj.constructor); // [Function: Object]
Object.prototype.toString.call()
Object.prototype.toString.call(); // [object Undefined]
Object.prototype.toString.call(""); // [object String]
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(new RegExp()); // [object RegExp]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call(new Error()); // [object Error]
类型转换
转为数值
Number() 适用于任何类型
let num1 = Number("Hello world!"); // NaN
let num2 = Number(""); // 0
let num3 = Number("000011"); // 11
let num4 = Number(true); // 1
parseInt(string, radix) 主要用于字符串
- 如果第一个字符不是数值字符、加号或减号,立即返回NaN
,这意味着空字符串也会返回 NaNlet num2 = parseInt(""); // NaN let num3 = parseInt("0xA"); // 10 let num4 = parseInt(22.5); //22 let num5 = parseInt("abc"); // NaN let num6 = parseInt("123abc") // 123 [1,2,3].map(parseInt) // [1, NaN, NaN] // map调用的回调会默认传入三个参数【当前元素,当前索引,当前数组】 // parseInt(1,0) => radix为undefined或者0时,相当于radix10 // parseInt(2,1) => 1进制的2??NaN // parseInt(3,2) => 2进制的3?? NaN
parseFloat(string) 主要用于字符串
- 只解析十进制
- 忽略2次出现的小数点
let num1 = parseFloat("1234blue"); // 1234 let num2 = parseFloat("0xA"); // 0 let num3 = parseFloat("22.5"); // 22.5 let num4 = parseFloat("22.34.5"); // 22.34 let num5 = parseFloat("0908.5"); //908.5 let num6 = parseFloat("3.125e7"); // 31250000
转为字符串
toString()
null和undefined没有toString()方法
String()
- 优先调用toString()
- null 转换为 ‘null’
- undefined 转换为 ‘undefined’
转为布尔值
- Boolean()
//除了以下六个转为 false 其他全部都为 true undefined null 0 -0 NaN ''
隐式转换
在 js 中,当运算符在运算时,如果两边数据不统一,CPU 就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算.这种无需程序员手动转换,而由编译器自动转换的方式就称为隐式转换
隐式转换规则
- 转成 string 类型:
+
(字符串连接符) - 转成 number 类型:
++/--
(自增自减运算符)+ - * / %
(算术运算符)> < >= <= == != === !===
(关系运算符) - 转成 boolean 类型:
!
(逻辑非运算符)
字符串连接符与算术运算符
+
左右有字符串则转为字符串拼接,否则转为数字计算
//+是字符串连接符: String(1) + 'true' = '1true'
console.log(1 + "true"); //1true
//+是算术运算符 : 1 + Number(true) = 1 + 1 = 2
console.log(1 + true); //2
// +是算术运算符 : 1 + Number(undefined) = 1 + NaN = NaN
console.log(1 + undefined); // NaN
// +是算术运算符 : 1 + Number(null) = 1 + 0 = 1
console.log(1 + null); //1
//
关系运算符
会把其他数据类型转换成 number 之后再比较关系
此时并不是按照 Number()的形式转成数字,而是按照字符串对应的 unicode 编码来转成数字
console.log("2" > "10"); //true '2'.charCodeAt() > '10'.charCodeAt() = 50 > 49 = true
console.log("2".charCodeAt()); //数字50
console.log("10".charCodeAt()); //数字49(默认返回第一个字符的编码,如果想要查询第二个字符可以传参下标)
//多个字符从左往右依次比较
console.log("abc" > "b"); //false 先比较'a' 和 'b', 'a' 与 'b'不等,则直接得出结果
console.log("abc" > "aad"); //true 先比较'a'和'a',两者相等,继续比较第二个字符 'b' 与 'a' ,得出结果
console.log("a".charCodeAt()); //数字97
console.log("b".charCodeAt()); //数字98
//2.3 特殊情况(无视规则):如果数据类型是undefined与null,,得出固定的结果
console.log(undefined == undefined); //true
console.log(undefined == null); //true
console.log(null == null); //true
//2.4 特殊情况(无视规则):NaN与任何数据比较都是NaN
console.log(NaN == NaN); //false
复杂数据类型的隐式转换
- 先使用
valueOf()
方法获取其原始值,如果原始值不是number
类型,则使用toString()
方法转成string
- 再将
string
转成number
运算
[1, 2] == "1,2"; //true 先将左边数组转成string,然后右边也是string则转成unicode编码运算
[1, 2].valueOf(); // [1,2]
[1, 2].toString(); // '1,2'
var a = {};
a == "[object Object]"; //true
a.valueOf().toString(); //[object Object]
逻辑非隐式转换与关系运算符
如果两个引用类型比较,会比较内存地址,注意要是其中有逻辑非运算符,非运算优先级会大于比较操作
- 空数组的 toString()方法会得到空字符串
''
- 空对象的 toString()方法会得到字符串
[object Object]
console.log(Boolean([])); // true
console.log(Boolean(![])); // false
// Boolean除了0,-0,null,undefined,false,''都转为true
//大坑
console.log([] == 0); //true []转数字为0
console.log(![] == 0); //true
// 这里有逻辑非运算符,会先转Boolean,![]转布尔false,转数字为0
//神坑
console.log([] == ![]); //true
// ![]转布尔false=>0,0和[]比较,[]转数字为0
console.log([] == []); //false // 内存地址不同
//史诗级坑
console.log({} == !{}); //false
// {}最终转number为NaN,右边转数字为0
console.log({} == {}); //false // 内存地址不同
值的比较
es6 新增Object.is()
判断
修复了转布尔值的bug
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0); // false
Object.is(NaN, 0 / 0); // true
function _Object.is(x,y){
if(!Object.is){
if(x===y){
return x!==0 || 1/x === 1/y
}else{
return x!==x && y!== y
}
}
}
hack技巧
- 转string
123+''
// ‘123’ - 转number
+123
// 123 - 位运算
- 向下取整
~~1.9 = 1 1.9 >> 0 = 1
- Math.floor(N/2)
124.9 >> 1 = 62
- 向下取整
js数据类型的判断与转换
http://yoursite.com/2022/02/24/js中数据类型转换/