用typeof、instanceof和Object.prototype.toString来判断JS数据类型和他们的区别

js/jq 专栏收录该内容
13 篇文章 0 订阅
  • 2021-01-06
    我自己不太常用判断JS数据类型,所以也不太熟悉,正好就放在一起讲一下吧。
  • 2021-01-07
    越整理东西越多,写的也有点乱了。另外这个标题我改来改去的也不知道怎么概括,大家将就看看吧,重要的是内容!我查了好多资料整理出来的~ 看完这个,哪怕是像我一样的小白也一定能理解的。

一、typeof


1. typeof的返回值

  • 简单数据类型(基本数据类型):Undefined、Null、Boolean、Number、String和Symbol。
  • 复杂数据类型(引用类型):Object(本质上是由一组无序的名值对组成的,包括对象,Function,Array)。
返回值代表意义
Undefined未定义
Boolean布尔
String字符串
Number数值
Object对象或null
Function函数
Symbol(ES6新增)symbol类型
Implementation-dependent宿主对象(由JS环境提供)
  • ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
  • 宿主对象:JS所运行的环境提供的对象比如:BOM中的Window、DOM中的document。


2. typeof为什么要区分object和function?

  1. 《JavaScript高级程序设计》:从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的。
  2. 在实际的使用过程中,有必要区分object和Function,所以typeof实现了这一功能。


3. typeof的语法

typeof是一个操作符而不是函数,所以用不用括号都可以。

  • typeof (表达式):对表达式做运算
  • typeof 变量名:对变量做运算。
console.log(typeof 15);	//'number'
console.log(typeof 'str');	//'string'


4. typeof的特殊返回值

//返回值:NaN(typeof返回值宗为字符串类型,但是NaN是个例外,他是数值类型)
console.log(typeof 1/0);
//返回值:'number'
console.log(typeof (1/0));
console.log(typeof NaN);
console.log(typeof Infinity);
//返回值:'string'
console.log(typeof typeof (1/0));
//返回值:'symbol'
console.log(typeof Symbol());
console.log(typeof Symbol('foo'));
//返回值:'undefined'
console.log(typeof undefined);
//返回值:'object'
console.log(typeof [1,2,3]);
console.log(typeof new String());
//返回值:'function'
console.log(typeof function(){});	
console.log(typeof Math.sin);
console.log(typeof (class c{}));	


5. typeof的迷惑行为和不足之处(当心踩坑)

  • typeof null会返回‘object’。
  • typeof 数组 会返回‘object’。
    因为特殊值null会被认为是一个空对象引用。
  • typeof 正则表达式
    在Safari 5以及之前版本,Chrome 7以及之前版本会返回‘function’,其他浏览器会返回‘object’。
  • typeof 宿主对象
    在IE6、7、8中,大多数的宿主对象返回‘object’而不是‘function’,如typeof alert返回‘object’。而在非IE浏览器或IE9以上(包含IE9)的浏览器中,返回‘function’。
  • typeof 对象,
    对于一些创建的对象(数组、null、部分浏览器中的正则和宿主对象),他们都会返回’object’。


二、instanceof


1. 为什么有了 typeof 运算符我们还需要 instanceof ?

  • typeof是判断参数是什么的实例,返回值为说明运算数类型的字符串。如果参数为引用类型,那么typeof会始终返回 ’ object ',所以用typeof来判断参数类型有很大的局限性。
  • 有时,我们需要判断某变量是否为某个对象的实例,那么我们会用到instanceof运算符。


2. instanceof 的定义和用法

instanceof是用来判断一个对象在其原型链中是否存在一个构造函数的prototype属性。

  • a instanceof b:判断a是否为b的实例,也可用于继承关系中。
  • 如果b是c的父对象,a是c的实例,那么 a instanceof b 与 a instanceof c 的结果都为true。
function Person(){}		//创建一个构造函数
const p1 = new Person();
console.log(p1 instanceof Person);		//true


3. instanceof 的判断原理

如果只看定义,大家可能像我一样不太理解原型链和prototype属性这些,
说白了,instanceof 就是可以用来判断一个变量是否是属于某个对象的实例,instanceof检测的是这个变量的原型属于谁。

  • instanceof的判断规则是沿着 Func 的 prototype 属性向上找,如果能找到同一个引用,就返回true,否则返回false。
  • 每个函数都有 prototype 属性(存储的是原型对象),每个原型对象都有 proto (隐式原型)指向它构造函数的原型对象(prototype)。对象没有 prototype 属性。

在这里插入图片描述

  • func._ proto_ 指向 Func.prototype
  • Func._ proto_ 指向 Object.prototype
  • 最终指向Object,也是验证了万物皆对象的思想。因此,func instanceof Func 和 func instanceof Object 的返回结果都是 true,func instanceof Function 的返回结果是 false。


4. instanceof的局限性


(1)instanceof无法直接判断原始数据类型
var str1 = 'hello word';
var str2 = new String('hello world');
console.log(str1 instanceof String);		//false
console.log(str2 instanceof String);		//true

我们可以这样来解决:

class PrimitiveString{
	static [Symbol.hasInstance](x){
		return typeof x === 'string'
	}
}
console.log('hello world' instanceof PrimitiveString);		//true

Symbol.hasInstance 可以理解为一个自定义 instanceof 行为的方法,上面代码的功能等于typeof (‘hello world’ === ‘string’)。


(2)instanceof 对于特殊类型无法判断
console.log(new Date() instanceof Date);		//true
console.log(new Date() instanceof Object);		//true
console.log([] instanceof Array);		//true
console.log([] instanceof Object);		//true

instanceof只能用来判断两个对象是否属于实例关系,而不能判断一个是里究竟属于哪种类型。



三、如何判断特殊类型


1. 数组判断方法

既然 typeof 和 instanceof 都不能判断数组类型,那么我们就没办法判断数组了吗?
当然不是,我们还可以用Array.isArray来区分数组和普通对象:

//Array.isArray
console.log(Array.isArray([1, 2, 3]));		// true
console.log(Array.isArray({obj: 123}));		//false


2. null判断方法

最简单也是最直接的方法,就是直接与null比较:

console.log( value === null );


四、Object.prototype.toString


除了上面的方法,Object.prototype.toString 也是一个很方便可以判断数据类型的方法。
(内容有点多,我纠结了半天要不要单独写,最后还是决定在这里简单说一下~)
Object.prototype.toString的用法非常简单,我举几个例子大家就明白它的用法了。


1. 判断基本类型

console.log(Object.prototype.toString.call(1));		//'[object Number]'
console.log(Object.prototype.toString.call(true));		//'[object Boolean]'
console.log(Object.prototype.toString.call(null));		//'[object Null]'
console.log(Object.prototype.toString.call(undefined));		//'[object Undefined]'
console.log(Object.prototype.toString.call('a'));		//'[object String]'


2. 判断引用类型

console.log( Object.prototype.toString.call({}) );		//”[object Object]”
console.log( Object.prototype.toString.call([]) );		//”[object Array]”
function fn(){}
console.log( Object.prototype.toString.call(fn) );		//”[object Function]”




  • 0
    点赞
  • 1
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值