前言
和TypeScript相比,js并没有特别严格的数据类型控制,除了存在一些隐式转换外,有时候数据类型的确定在项目中也尤为重要,不然很容易导致一些无关的报错焦头烂额(TypeError),最近项目中也遇到了这个小问题。
本文主要讲的就是数据类型的判断与一些简单的数据转换。
javascript数据类型
1,简单数据类型:String,Number,Boolean,undefined,null,Symbol(es6新增,symbol值能作为对象属性的标识符),BigInt(es11新增,表达表示大于 2^53 - 1 的整数)
2,引用数据类型:Object,可细分为 Array 、Function、RegExp、Date等
数据类型判断
typeoftypeof操作符返回字符串,表示未经计算的操作数的类型(这句话是官方解释),什么意思呢,根据我自己的总结就是
typeof一般用来检验简单数据类型,返回的是基本类型用字符串表示,而复杂数据类型中function返回的是Function,然后其他都返回Object,其中null特殊,表示一个空对象
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof function(){} // 'function'
instanceofinstanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上(官方)
object instanceof constructor
因为上述typeof只能检测出简单数据类型,那么复杂数据类型,就一般会配合instanceof来使用,而且instanceof只能检测复杂数据类型,null和undefined会报错
// 定义构造函数
let Person = function() {}
let person = new Person()
person instanceof Person // true
- 手写实现一个
instanceof
function newInstanceOf(leftValue, rightValue) {
// 判断左右两边值
if (typeof leftValue !== 'object' || rightValue == null) {
return false
}
const rightProto = rightValue.prototype
leftValue = leftValue.__proto__
while (true) {
if (leftValue === null) return false
// 找相同类型
if (leftValue === rightProto) return true
leftValue = leftValue.__proto__
}
}
- Object.prototype.toString.call() Object.prototype.toString()返回一个表示对象的字符串。
因为对于数字,数组,字符串类型等,他们重写了toString方法,所以我们用Object来进行类型判断,此会根据call方法的this来改变this指向,返回一个[object xxx]这样的字符串,后面表示的就是这个对象的类型。可以理解为用谁就call谁
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call() // "[object Number]"
Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call(object) // "[object Object]"
var o = new Object();
o.toString(); // "[object Object]"
JavaScript类型转换
- 显示转换
- Number()
- String()
- Boolean()
- parseInt()
- toString()
这里就介绍下 parseInt() 和 Number.prototype.toString()
parseInt() 函数
parseInt(string, radix)、
string | 必需。要被解析的字符串。
radix | 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
parseInt("10"); //返回 10
parseInt("19",10); //返回 19 (10+9)
parseInt("11",2); //返回 3 (2+1)
parseInt("17",8); //返回 15 (8+7)
parseInt("1f",16); //返回 31 (16+15)
parseInt("010"); //未定:返回 10 或 8
// 如果转换的值是null,undefined,boolean,均转换为NaN
console.log(parseInt('+12.3')) // 12 首位为符号位,其余为为数值,转换为整数
console.log(parseInt('1+2.3')) // 1 符号位出现在其他位置,保留符号位前面的数值
console.log(parseInt('0xa')) // 10
console.log(parseInt('010')) // 10 不解析八进制
console.log(parseInt('123ac')); // 123
console.log(parseInt('0101', 2)) // 5
parseInt() 第二个参数会把第一个参数以第二个参数的进制来解析,返回十进制的值 toString() 会将数值以二进制、八进制、十六进制,乃至其他任意有效进制格式表示
Number.prototype.toString()
NumberObject.toString(radix)
radix | 可选。规定表示数字的基数,使 2 ~ 36 之间的整数。若省略该参数,则使用基数 10。但是要注意,如果该参数是 10 以外的其他值,则 ECMAScript 标准允许实现返回任意值
指定要用于数字到字符串的转换的基数(从2到36)。如果未指定 radix 参数,则默认值为 10。
一般情况下,调用 toString()方法不必传递参数,但是,在调用数值的 toString()方法时,可以传递一个参数:输出数值的基数。默认情况下,toString()方法以十进制格式返回数值的字符串表示。而通过传递基数,toString()可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格 式表示的字符串值
var num = 10;
console.log(num.toString()) //"10"
console.log(num.toString(2)) //"1010"
console.log(num.toString(8)) //"12"
console.log(num.toString(16)) //"a"
console.log(typeof String(null)) //string
console.log(Number('+12.3')) //12.3
console.log(Number('1+2.3')) // NaN
console.log(Number('123ac')) // NaN
- 隐式转换
通常来讲,隐式转换发生在以下 比较运算符(
==、!=、>、<)、if、while这些需要布尔值地方 和 算术运算(+、-、*、/、%) 中
- 转换为布尔值 undefined, null, false, +0, -0, NaN, "" 都会转换为false,其余为true
- 转换为字符串
+运算中,一旦存在字符串,会自动把两边的值转换为字符串 - 转换为数值
除了
+有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值
log
console.log(Number.prototype.toString()); // "0"
console.log('+',Boolean(' ')); // + true
console.log(String('"5"'),'<',String("'10'")); // "5" < '10'
console.log(String(null),'+','10'); // null + 10
console.log(Function()); // f anonymous(){}
console.log(+true) // 1
console.log("5" < "10") // false
console.log("bat" > 'bytedance') // false
console.log(null+10) // 10
console.log(123['toString'].length + 123); // 124
;(function(){
'use strict';
fun();
function fun() {
console.log('aabb'); // aabb
}
})
var a = [1, 2, 3],
b = [1, 2, 3],
c = [1, 2, 4];
console.log(a == b); // false
console.log(a === b); // false
console.log(a > c); // false
console.log(a < c); // true
console.log("5"+3); // 53
console.log(null === undefined); // false
console.log(null == undefined); // true
console.log(!null); // true
console.log(isNaN(1+null)); // false
console.log(isNaN(1+undefined)); // true
console.log(1 == true); // true
console.log(0 === false); // false
console.log(1+'1'+false); // 11false
console.log('2' + ['a',2]); // 2a,2
结语
写的不好,有错误的地方烦请各位大佬多多指教,感恩家人感恩🙏
🚩祝各位一路顺风,顶峰相见