js是一种弱类型语言,拥有动态数据动态,相同的变量可用作不同的类型。

基本数据类型:Number,string,Boolean,Symbol(es6)

特殊类型:undefined,null

以上类型为原始数据类型

引用类型:Object, Array,function,Date

判断类型

1、使用 typeof
typeof 可以检测Number,String,Boolean,undefined,null,function类型。
但是检测 Object 和 Array 时,返回的都是对象型 Object。

2、使用 instanceof 判断 object 和 array

let a = []; // 
a instanceof Array;  // true
a instanceof Object; // false

let o = {};
o instanceof Object; // true
o instanceof Array; // false

同时 instanceof 可以判断一个实例是否属于某种类型。

let fn = function(){};
fn instanceof function; // true
let fn_copy = new fn();
fn_copy instanceof function; // true

instanceof 实现原理,只要右边的 prototyp 在左边变量的原型链上即可,所以 instanceof 在查找过程中会遍历在左边变量的原型链,知道找到右边变量的 prototype ,如果查找失败会返回 false;

3、使用 constructor
当一个函数 fn 被定义时,ls引擎会为 fn 添加 prototype 原型,然后会在 prototype 上添加一个 construtor 属性,并让其指向 fn 的引用。但是 null 和 undefined 时无效的对象,因为不会有 constructor 的存在。
js 对象的 constructor 是不稳定的,主要体现在自定义对象上,当重写改变 prototype 时,原有的 constructor 会丢失, constructor 会默认为Object;

4、使用 Object.prototype.toString 是目前被认为最准确的方法
toString 是 Object 原型对象上的方法,该方法默认返回其调用者的具体类型,更严格的说,是 toString 运行时 this 指向的对象类型,返回的类型格式时 [Object, XXX] ,XXX 是具体的数据类型,包括:string; Number; Boolean; undefined; null; function; Date; Array; RegExp; Error; HtmlDomcument; 等。基本上所有的对象都可以通过此方法获得。

object.prototype.toString.call("a"); // [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(new function()); // [object, function]
object.prototype.toString.call(new Date); // [object, date]
object.prototype.toString.call([]); // [object, Array]
object.prototype.toString.call({}); // [object, Object]
object.prototype.toString.call(new RegExp()); // [object, RegExp]
object.prototype.toString.call(new Error()); // [object, Error]
object.prototype.toString.call(document); // [object, document]
object.prototype.toString.call(window); // [object, global]

从原型链角度讲,所有的对象的原型链最终都指向了 Object , 按照 js 查找变量规则,其他对象都可以直接访问到 Object 的 toString 方法,事实上大部分对象都实现了自身的 toString 方法,因此要使用 call 来强制执行 Object 的 toString 方法。

5、数字类型-- isNaN() 和 Number.isNaN()
isNaN == is not a number
因此当判断的数据类型为数字类型时返回值为: false;

isNaN 原理是像isNaN 传递一个参数,他通过Number()的方法,尝试将参数转化为数字 Number 类型,如果转化成功返回 false, 转化失败返回 true ; 所以 isNaN 是判断 该变量能不能被转化为数字类型,不能转化后返回 NaN , Number(NaN) 为 true:

var num = 123;
console.log(Number(num)); // 123
console.log(isNaN(num)); // false

var num_str = '123';
console.log(Number(num_str )); // 123
console.log(isNaN(num_str )); // false

var obj = {};
console.log(Number(obj)); // NaN
console.log(isNaN(obj)); // true

var arr = [];
console.log(Number(arr)); // 0
console.log(isNaN(arr)); // false

var boolean1 = true;
console.log(Number(boolean1)); // 1
console.log(isNaN(boolean1)); // false

var boolean1 = true;
console.log(Number(boolean1)); // 0
console.log(isNaN(boolean1)); // false

而 Number.isNaN() 不会进行数据类型转化,Number.isNaN() 只会严格的判断参数类型为 NaN:

console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(12)); // false
console.log(Number.isNaN("123")); //false
console.log(Number.isNaN({})); //false
console.log(Number.isNaN([]));  // false

6、可用正则判断数字类型:

var num = 1;
var reg=/^[0-9]+.?[0-9]*$/; //判断字符串是否为数字 ,判断正整数用/^[1-9]+[0-9]*]*$/
console.log(reg.test(num))

7、判断数组可以用 Array.isArray();
参数为 数组类型时返回 true; 不是数组类型时返回 false;

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false 
console.log(Array.isArray(12)); // false

function add(){
    console.log(Array.isArray(arguments)); // false
}
add(1,2,3);

console.log(Array.prototype); // true // Array.prototype也是一个数组

如果后面再学到,会继续积累,也希望各位有看到不足,可以及时补充。