一.类型检测
1.typeof方法
typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算。 typeof运算符的返回值包括如下几种:
- 'undefined' --未定义的变量或值
- 'boolean' --布尔类型的变量或值
- 'string' --字符串类型的变量或值
- 'number' --数字类型的变量或值
- 'object' --对象类型的变量或值,或者null(这个是js历史遗留问题,将null作为object类型处理,因为设计的时候
null是全 0,而对象是000开头,所以有这个误判) - 'function' --函数类型的变量或值
简单的示例
console.log(typeof a); //'undefined'
console.log(typeof(true)); //'boolean'
console.log(typeof '123'); //'string'
console.log(typeof 123); //'number'
console.log(typeof NaN); //'number'
console.log(typeof null); //'object'
var obj = new String();
console.log(typeof(obj)); //'object'
var fn = function(){};
console.log(typeof(fn)); //'function'
console.log(typeof(class c{})); //'function'
console.log(typeof([])); //'object'
注意:这里typeof检测后返回的都是字符串,所以
typeof(typeof(11)); //"string"
另外:
typeof(null)=Object
typeof(Object)=function //内置构造器的类型都是function
2.instance of 方法
typeof检测出Object类型的变量后不能进一步检测出是哪种Object(比如Array,Date)
而instanceof用于判断一个变量是否某个对象的实例比如:
console.log([] instanceof Array);//true
console.log({} instanceof Object);//true
console.log(/\d/ instanceof RegExp);//true
console.log(function(){} instanceof Object);//true
console.log(function(){} instanceof Function);//true
不过它不能判断js的基础数据类型
console.log('' instanceof String);//false
console.log(1 instanceof Number);//false
除此之外,instanceof最大的用处便是用来检测自定义类,并且由于内部机制是通过instanceof是通过判断左边对象的原型琏中是否存在右边构造函数的prototype来判断类型,所以它也能检测继承关系
一般情况
function User(name){this.name = name}
var user = new User()
user instanceof User //true
还有继承的情况
function Foo() {{
this.name = 'wyh'
this.age = '23'
}
function GFoo() {
this.country = 'China'
}
Foo.prototype = new GFoo()
let foo = new Foo()
console.log(foo instanceof Foo) // true
console.log(foo instanceof GFoo) // true}}
3.使用Object.prototype.toString.call()
调用Object.prototype.toString.call()方法可以判断出某个变量属于哪种js的内置对象,并且输出标准格式。
检测基本类型
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(“abc”);// "[object String]"
Object.prototype.toString.call(123);// "[object Number]"
Object.prototype.toString.call(true);// "[object Boolean]"
检测引用类型
Function fn(){
console.log(“test”);
}
Object.prototype.toString.call(fn); // "[object Function]"
var date = new Date();
Object.prototype.toString.call(date); // "[object Date]"
var arr = [1,2,3];
Object.prototype.toString.call(arr); // "[object Array]"
var reg = /[hbc]at/gi;
Object.prototype.toString.call(reg); // "[object RegExp]"
注意:无法检测自定义类型
function Person(name, age) {
this.name = name;
this.age = age;
}
var person = new Person("Rose", 18);
Object.prototype.toString.call(arr); // "[object Object]"
4.实现一个类型判断函数
思路:
- 判断 null
- 使用 typeof 判断基础类型
- 使用
Object.prototype.toString.call(target)来判断引用类型
二.类型转换
1,显式类型转换
Number()函数
Number函数可以直接将括号里面的内容转化为类型为number的数字,对于无法转化的也不会报错,而是返回一个NaN。
注意:将null转化为数字返回0,将undefined转化为数字返回NaN
Number("123") //123
Number('abc') //NaN
Number(null) //0
Number(underfined) //NaN
String()函数
String函数和Number一样,是可以直接将括号里面的内容转换为字符串的形式.
要注意的是
- 当转化的是 null undefined这一类值的时候,返回的是字符串形式的"null"和"undefined"。
- 在转化1.00和1.10这类浮点数的时候,会自动消掉后面的0
String(999) //"999"
String(null) //'null'
String(undefined) //"undefined"
String(1.00) //1
parseInt()函数
这个函数的作用,是将括号里面的值转化为整型。 可以接收第二个参数,即被转化的数字的进制类型
不过要注意的是
- 使用这个函数转化类似于'123abc'的值不会报错,而是返回数字 123 ,这是因为这个函数在转化的时候,会默认停止在第一位非数字位.
- 在转化浮点数的时候,也只会保留整数部分。
- 对于完全无法转化的变量函数返回一个NaN。
parseInt('16',8) //14 即将8进制的16转化为10进制
parseInt("11aaa") //11
parseInt("aaa11") //NaN
parseInt('1.23abc') //1
parseInt('1.23') //1
parseFloat()函数
这个函数和ParseInt()的特点几乎是相同的,不同的部分自然是这个函数可以转化的不再局限于整数,还可以转化浮点数。
console.log(parseFloat("123")); //123
console.log(parseFloat("123.123")); //123.123
console.log(parseFloat("123.00")); //123
console.log(parseFloat("123.12aaa31")); //123.12
console.log(parseFloat("aaa123.1231")); //NaN
console.log(parseFloat("aaa")); //NaN
toString()方法
这个方法与String()类似,但是有两个不同点,
- 一个是这个方法是在变量后面加.toString来调用
- 一个是这个方法不能转化"null"和"undefined"
var a = 123
console.log(a.toString()); //"123"
var b;
console.log(b.toString()); //"报错"
var c = null;
console.log(c.toString()); //"报错"
Boolean()方法
这个方法将括号中的内容转化为布尔值,转化的只要是对象最后都会返回true。
console.log(Boolean(1)); //true
console.log(Boolean(0)); //false
console.log(Boolean("")); //false
console.log(Boolean(undefined)); //false
console.log(Boolean([])); //true
console.log(Boolean({})); //true
2,隐式类型转化
isNaN()
作用是判断一个变量 是不是 NaN,但是它在判断的时候做了一个类型转化,即先对括号中的内容进行Number的转化。
最后,不能转化为Number的都将返回false,所以它不能明确判断一个变量是不是NaN
isNaN(123) //返回false
isNaN('abc') //返回true
isNaN(undefined) //返回true
isNaN(null) //返回false
isNaN(NaN) //返回True
++/-- +/-一元正负
先调用Number()进行类型转换,然后再对变量进行运算符操作
++ '123' //返回number类型的124
++ 'abc' //返回number类型的NaN
加法运算符: +
当运算符两侧有一个为String,调用的隐式方法为String()
123+"aaa"
//"123aaa"
123+"111"
//"123111"
其他运算符: - * / %
先对运算符两侧的变量执行Number()类型转换,然后再做运算
"a" - 1 //结果为NaN
1 * 'a' //结果为NaN
与或非: && || !
会使用Boolean()方法对表达式两边做隐式类型转换
比较运算符: > >= < <=
两边有一个为非数字,都会先转化为数字(true转化为1,false转化为0),再进行比较,返回一个布尔值。
等于: ==
这个比较会先把两边转化为相同类型,然后比较其值是否相等,注意 NaN==NaN返回false
3,装箱转换和拆箱转换
装箱转换:把基本数据类型转化为对应的引用数据类型的操作
每当读取一个基本类型的时候,后台就会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法来操作这些数据。
比如
var s1 = "abc";
var s2 = s1.indexOf("a")
变量s1是一个基本类型值,它不是对象,它不应该有方法。但是js内部为我们完成了一系列处理(即装箱),使得它能够调用方法,实现的机制如下:
- 创建String类型的一个实例;
- 在实例上调用指定的方法;
- 销毁这个实例; 后台隐式做了如下操作
var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;
这样就完成装箱,我们也就能在s1上调用方法了
拆箱转换:将引用类型对象转换为对应的值类型对象
它是通过引用类型的valueOf()或者toString()方法来实现的。如果是自定义的对象,你也可以自定义它的valueOf()/tostring()方法,实现对这个对象的拆箱
比如
var num = new Number(10);
console.log(typeof(num)); //Object
num = num + 2;
console.log(typeof(num)); //Number
var o = {
valueOf: () => { console.log("valueOf"); return 1 },
toString: () => { console.log("toString"); return 1 }
}
console.log(o + "aaa"); // "1aaa"
console.log(o * 2); // 2
注意:一般情况下它会先调用你的valueOf方法,如果发现不存在, 才会调用toString方法。
最后
感谢你能看到这里,欢迎在评论区留言交流,如果可以的话,不妨点个赞再走呀。