js中几种判断数据类型的方法原理及难点(通俗易懂)

看这篇博客前确保你了解了原型与原型链的知识,原理大多涉及到了原型与原型链的知识。
可看我这篇博客了解原型与原型链
js高级之原型与原型链

1.Object.prototype.toString.call/apply()
结论
首先抛出结论:带着结论我们来理解这个方法

object.prototype.toString.call()方法其实是利用 Object.prototype.toString()方法可以返回“[obejct 对象构造函数名]” 的原理来确定数据类型,并且js中所有对象都是Object的实例,可以使用call/apply 调用 Object.prototype原型对象的tostring()方法

Object.prototype.toString.call/apply() 可以判断任何数据类型

不存在浏览器兼容问题

判断基本数据类型

console.log(Object.prototype.toString.call('d')) // [object String]
console.log(Object.prototype.toString.call(8)) // [object Number]
console.log(Object.prototype.toString.call(false)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call(Symbol(1))) // [object Symbol]

判断引用数据类型

console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(function a(){})) // [object Function]
console.log(Object.prototype.toString.call(/a+/)) // [object RegExp]

Object.prototype.toString.call/apply() 原理

Object.prototype代表Object的原型对象,里面存储了很多方法例如:toString,length,等等而toString方法返回的类型是“[obejct 对象构造函数名]”,上面事例中可以看到假如我判断一个对象

console.log(Object.prototype.toString.call({})) // [object Object]

返回类型第一个是object ,第二个是我传入的对象的构造函数名,这里传入了一个实例对象,通过原型链可知对象的实例对象指向的构造函数名为Object,所以输出了 [object Object],而所有的js中所有对象都是Object的实例所以都可以通过原型链访问到这个方法。所以就可以判断数据类型了。
2.typeof

最常用的但有缺陷

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object    
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object

其中数组、对象、null都会被判断为object,其他判断都正确。

3.instanceof

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

可以看到,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。instanceof 运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
那为什么不能判断基本数据类型呢?

首先我们知道instanceof的原理是根据该实例对象的构造函数是否等于后面一个构造函数,
而既然不能判断基本数据类型说明 2 ,‘str’,等基本数据类型并没有被实例化成对象。
代码为证:

console.log(new Number(2) instanceof Number);
console.log(new Boolean(true) instanceof Boolean);
console.log(new String('str') instanceof String);

在这里插入图片描述
可以看到当我使用new实例化基本数据类型时判断为true,进一步说明2 ,‘str’,等基本数据类型在没有new实例化成对象都并不是实例对象。

4.constructor

原理很简单:对象通过constructor 来访问它的构造函数

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true


constructor有两个作用,一是判断数据的类型,
二是对象实例通过 constrcutor 对象访问它的构造函数(原型链知识)。
需要注意,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了:

创作不易如有错误欢迎指出

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值