javaScript 判断数据类型 NaN的判断
基本数据类型:string boolean number null undefined symbol
引用类型:object
基本类型也称为简单类型,由于其占据空间固定,是简单的数据段,为了便于提升变量查询速度,将其存储在栈中,即按值访问。
引用类型也称为复杂类型,由于其值的大小会改变,所以不能将其存放在栈中,否则会降低变量查询速度,因此,其值存储在堆(heap)中,而存储在变量处的值,是一个指针,指向存储对象的内存处,即按地址访问。引用类型除 Object 外,还包括 Function 、Array、RegExp、Date 等。
Q: 如何判断变量的数据类型?
-
typeof
这里首先想到的是借助typeof
操作符,但是它有一定的局限性:
- 基本类型仅能判断除
null
以外的基本类型 - 引用类型,除
function
以外,一律返回object
类型
typeof Symbol(); // symbol 有效
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof new Function(); // function 有效
typeof null; //object 无效
typeof [] ; //object 无效
typeof new Date(); //object 无效
typeof new RegExp(); //object 无效
-
instanceof
instanceof 是基于原型链的,用来判断 A 是否为 B 的实例A instanceof B
[] instanceof Array; //true
{} instanceof Object;//true
new Date() instanceof Date;//true
new RegExp() instanceof RegExp//true
由于 null 和 undefined 属于基本数据类型,instanceof 无法判断
(使用instanceof 操作符检测其他基本类型的值,则该操作符始终会返回false,因为基本类型不是对象)
null instanceof null //error "TypeError: Right-hand side of 'instanceof' is not an object
undefined instanceof undefined //error "TypeError: Right-hand side of 'instanceof' is not an object
'' instanceof String // false
1 instanceof Number // false
3. toString (常用的推荐方法)
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] ,这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
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([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; // [object global] window 是全局对象 global 的引用
Q: 如何判断变量的为NaN?
type / value / variable
variable是存放value的容器,而value是有着type概念的,但是容器variable是没有type的概念的
const a = 'foo';
容器 variable a 装着 value 'foo', value 'foo' 的type是string
NaN是一个放在 global(浏览器里是window)对象里的一个value,是一个代表Not-A-Number的value.
引用:https://juejin.im/post/59f7c5f551882529452fba6b
console.log(typeof NaN); // number
显然NaN是一个 value, 这个 value 的 type 是 number
NaN有个特性(两个NaN不相等)
console.log(NaN===NaN); // false
利用这个特性 isNaN()
就出现了,但是 isNaN()
只要不是number就会返回 true
isNaN(NaN); // true
isNaN('A String'); // true
isNaN(undefined); // true
isNaN({}); // true
为了弥补这个bug,需要先判断数据类型是否为number,然后再判断是否为NaN
const NumberisNaN = function(n) {
return (
typeof n === "number" && window.isNaN( n )
);
};
ES6引入了 Number.isNaN()
Number.isNaN(NaN); // true
Number.isNaN('A String'); // false
Number.isNaN(undefined); // false
Number.isNaN({}); // false
还有一种简单的判断方式
const NumberisNaN = function(n) {
return n !== n;
}
console.log(NumberisNaN(undefined)); // false
console.log(NumberisNaN({})); // false