一.类型检测
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
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最大的用处便是用来检测自定义类,并且由于内部机制是通过原型链来实现的,所以它也能检测继承关系
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
- 判断基础类型
- 使用
Object.prototype.toString.call(target)
来判断引用类型
二.类型转换
1,显式类型转换
Number()函数
Number函数可以直接将括号里面的内容转化为类型为number的数字,对于无法转化的也不会报错,而是返回一个NaN。
Number("123") //123
Number('abc') //NaN
String()函数
String函数和Number一样,是可以直接将括号里面的内容转换为字符串的形式,不过这里要提一下,当转化的是 null undefined这一类值的时候,返回的是字符串形式的"null"和"undefined"。
String(999) //"999"
String(null) //'null'
String(undefined) //"undefined"
parseInt()函数
这个函数的作用,是将括号里面的值转化为整型,不过要注意一点的是,使用这个函数转化类似于’123abc’的值不会报错,而是返回数字 123 ,这是因为这个函数在转化的时候,会默认停止在第一位非数字位,除此之外,在转化浮点数的时候,也只会保留整数部分。这个函数除了需要转化的数字之外,还可以接收第二个参数,即被转化的数字的进制类型,对于完全无法转化的变量函数返回一个NaN。
parseInt('16',8) //14 即将8进制的16转化为10进制
parseInt("11aaa") //11
parseInt("aaa11") //NaN
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"
由于这个特性,所以一般的变量加空串就可以直接转化为string
- * / %
先对运算符两侧的变量执行Number()类型转换,然后再做运算
"a" - 1 //结果为NaN
1 * 'a' //结果为NaN
&& || !(与或非)
会使用Boolean()方法对表达式两边做隐式类型转换
> >= < <=
两边有一个为非数字,都会先转化为数字(true转化为1,false转化为0),再进行比较,返回一个布尔值。
==
这个比较会先把两边转化为相同类型,然后比较其值是否相等,注意 NaN==NaN返回false
===
这个意为绝对等于,不会转化类型,要两边的值和类型均相同才会返回true