10

JS数据类型检测typeof、instanceof、constructor、Object.prototype.toString.call(va...

 4 years ago
source link: https://blog.csdn.net/Lele___/article/details/111473045
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JS数据类型检测typeof、instanceof、constructor、Object.prototype.toString.call(val)的区别

original.png
置顶 Lele___ 2020-12-21 14:57:16 articleReadEyes.png 1994

数据类型检测的四种方式

typeof

不能细分对象类型的值,都是返回“object”,函数检测返回“function”。
typeof 10:number
typeof new Number(10):object
typeof true:boolean
typeof new Boolean(true):object
typeof “aaa”:string
typeof new String(“aaa”):object
typeof null:object

  • 底层原理:
    typeof是按照“值”在计算机中存储的二进制值来检测的,凡是以000开始的都认为是对象(null:00000)。
    优点:检测原始值类型和函数类型方便。

instanceof

原本是检测某个对象是否是某个类的实例,临时拉来做数据类型检测,弥补typeof的一些不足,可以细分部分对象。
let arr = [];
arr instanceof Array

  • 底层原理
    arr instanceof Array,首先查找arr[Symbol.hasInstance]是否存在,如果存在基于这个检测Array[Symbol.hasInstance](arr)。如果没有则基于原型链__proto__查找,只要Array.protoType出现在arr的原型链上,返回结果就是true。
    arr[Symbol.hasInstance]
    Array[Symbol.hasInstance](arr)
    arr.proto == Array.prototype
    缺点:
    1.不能检测原始值类型;
    2.原型链可以重构,导致结果不准确;

constructor

和instanceof类似,都是临时用做数据类型检测使用的,constructor原型可以重构,导致结构不准确。
相对于instanceof,constructor可以检测原始值类型,但是只会基于原型链上的直属类检测。
let arr = [];
arr.constructor == Array ------------- true
arr.constructor == Object -------------- false
ps:因为arr.constructor直接指向的是Array

Object.prototype.toString.call();

除了null/undefined,大部分数据类型所属类的原型上,都有toString方法;但是所有的toString方法都是转换为字符串的只有Object原型上的toString方法是检测数据类型的。
优点:结果准确
返回值:“[object ?]”
let obj = {};
obj.toString.call(1)------------------- “[object Number]”
obj.toString.call(“1”)------------------- “[object String]”
obj.toString.call(true)------------------- “[object Boolean]”
obj.toString.call(new Date(2020-12-12))-- “[object Date]”
obj.toString.call(function(){})------------------- “[object Function]”
obj.toString.call(null)------------------- “[object Null]”
obj.toString.call(undefined)-----------------"[object Undefined]"
obj.toString.call([])-----------------"[object Array]"

  • 底层原理:
    先找要检测值[Symbol.toStringTag],先找私有的,如果找不到再找所属类原型上的,返回的属性值就是“?”;
    如果找不到Symbol.toStringTag,则返回当前示例所属构造函数的名字;
    let f =1;
    f[Symbol.toStringTag]-------undefined
    f.constructor[Symbol.toStringTag]-------undefined
    f.constructor.name -------“Number”

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK