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

一、typeof

1. typeof的返回值


简单数据类型(基本数据类型):Undefined、Null、Boolean、Number、String、Symbol。
复杂数据类型(引用类型):Object(本质上是由一组无序的名值对组成的,包括对象,Function,Array)。
 
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的迷惑行为和不足之处(当心踩坑)


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


二、instanceof

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


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


2. instanceof 的定义和用法


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

  1. a instanceof b:判断a是否为b的实例,也可用于继承关系中。
  2. 如果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]”



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值