js类型检测方法

参考
Object.prototype.toString.call() 为什么有用?
JavaScript 的数据类型及其检测

一、js类型
1. 分类
基本数据类型引用数据类型
2. 基本数据类型
  • Number
  • Boolean
  • Undefined
  • Null
  • String
  • Symbol
特点:

① 存放在栈区:原始数据类型直接存储在栈中的简单数据段,其占据空间小、大小固定,属于被频繁使用的数据。
② 值的比较:==只进行值的比较,在比较时会进行数据类型的隐式转换。===不仅进行值的比较,还要进行数据类型的比较。

console.log(1==true)//true
console.log(1===true)//false
3. 引用数据类型
  • 统称为Object,主要包括对象、数组和函数
特点

① 同时保存在栈内存和堆内存中:引用数据类型存储在堆中的对象有占据空间大、大小不固定的特点。如果存储在栈中,将会影响程序运行的性能。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。
在这里插入图片描述
② 比较是引用的比较:当比较两个引用变量时,无论是==还是===,都比较的是两个变量的引用是否一致。(这里注意:当比较引用中的基本数据类型值时,==仍为值比较,===为带数据类型的值比较)

let obj1 ={
        a:{
            b:3
        }
    }
    let obj2 = {
        a:{
            b:3
        }
    }
    console.log(obj1.a.b==obj2.a.b)//true
    console.log(obj1.a==obj2.a)//false
二、js检查数据类型
1. typeof
  • typeof返回一个表示数据类型的字符串,返回结果包括:stringnumberbooleansymbolundefinedfunctionobject
  • typeof无法检测出nullarray的类型,检测出来这两个都是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 无效
2. instanceof
  • instanceof来判断A是否是B的实例:A instanceof B
  • instanceof运算符来测试一个对象在其原型链中是否存在一个构造函数的prototype属性。(A instanceof B中,对象为A,构造函数为B
  • 通过instanceof检测nullundefined都不是对象类型
[] instanceof Array // true 
{} instanceof Object // true 
new Date() instanceof Date // true
new RegExp() instanceof RegExp // true 
Array.isArray([]); // true
instanceof的三大弊端
① 对于基本数据类型来说,字面量方式创建出来的结果和实例方式创建出来的是有区别的。从严格意义上来讲,只有实例创建出来的结果才是标准的对象数据类型值,也是标准的 Number 这个类的一个实例;对于字面量方式创建出来的结果是基本的数据类型值,不是严谨的实例,但是由于 JS 的松散特点,导致了其可以使用 Number.prototype 上提供的方法。
console.log(1 instance of Number)//false
console.log(new Number(1) instanceof Number)//true
② 只要在当前实例的原型链上,我们用其检测出来的结果都是true。但在类的原型继承中,我们最后检测出来的结果未必准确。
③ 对于特殊的数据类型nullundefined。他们所属的类是NullUndefined。但是浏览器把这两个类保护起来了,不允许我们在外部访问

在这里插入图片描述

3. 严格运算符===

只能用于判断基本数据类型数据。

let aaaa = null;
    let bbbb = null;
    console.log(aaaa===bbbb)//true
    
    let aaaa = undefined;
    let bbbb = undefined;
    console.log(aaaa===bbbb)//true


4. constructor

constructor可以检测当前对象的直属类,而不能检测原型链上的所有。它还可以处理基本数据类型的检测

 let arr = new Array();
 console.log(arr.constructor===Array)//true
  console.log(arr.constructor===Object)//false
 console.log((1).constructor === Number)//true
 console.log(reg.constructor=== RegExp);//true
弊端
nullundefined是无效的对象,因此不会有constructor存在的。
② 函数的constructor不稳定,主要是类的原型重写时,在重写的过程中可能会把之前的constructor覆盖掉,这样检测出来的结果是不准确的。
5. Object.prototype.toString.call()
  • Object原型链上的toString方法不是用来转换成字符串的。它的作用是返回当前方法执行的主体(方法中的this)所属类的详细信息,即[object Object],其中第一个object代表当前实例是对象数据类型的(这个是固定不变的),第二个object代表的当前this所属类的名称。
  • 所有类都是继承于Object类,故在创建所有类的实例时,理应来说可以调用到Object原型对象的toString方法。而除了Object类的实例以外,其余的类调用toString方法都是将其本身输出,这是因为所有类在继承Object类时重写了toString方法,故在调用时,调用的都是重写过后的toString方法,而非Object原型对象上的toString方法。当把所有类上的重写后的toString方法删除后,在通过该类实例调用toString方法时,调用的便是Object原型对象上的方法了(见例2)
  • 一般只有实例可以调用toString方法,但我们在实践中发现,1/true/"111"也可以调用toString方法,这是因为在调用该方法时,会将原始值包装成对象后再进行调用
Object.prototype.toString.call('') ; // [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(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( newError()) ; // [object Error]
Object.prototype.toString.call( document) ; // [object HTMLDocument]
Object.prototype.toString.call( window) ; //[object global] window是全局对象global的引用
//例2

// 定义一个数组
var arr = [1, 2, 3]

// 数组原型上是否具有 toString() 方法
console.log(Array.prototype.hasOwnProperty('toString')) //true

// 数组直接使用自身的 toString() 方法
console.log(arr.toString()) // '1,2,3'

// delete操作符删除数组原型上的 toString()
delete Array.prototype.toString

// 删除后,数组原型上是否还具有 toString() 方法
console.log(Array.prototype.hasOwnProperty('toString')) //false

// 删除后的数组再次使用 toString() 时,会向上层访问这个方法,即 Object 的 toString()
console.log(arr.toString()) // '[object Array]'
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值