JavaScript中的数据类型检测原理
专题汇总-数据类型检测
- typeof
- instanceof & constructor
- Object.prototype.toString.call([value])
- 封装一个数据类型检测的方法库
typeof
/*
typeof:用来检测数据类型的运算符typeof [value]
@return首先是个字符串字符串中包含对应的数据类型,例如:"number","string","object","boolean","undefeined","symbol","function"
@局限性不能具体区分对象数据类型的值typeof null //"object"typeof [] //"object"typeof {} //"object"typeof /^$/ //"object"
@优势使用方便,所以在真实项目中,我们也会大量应用它来检测,尤其是在检测基本类型值(除null之外)和函数类型值的时候,它还是很方便的
*/
function func(n,m,callback){//=>ES6:func(n=0,m=0)//=>检测形参的值是否为undefinedn === "undefined"? n=0 : null;typeof m ==="undefined" ? m=0 : null;//=>基于逻辑或逻辑与处理(瑕疵:不仅仅是不传赋值默认值,如果传递的值是假也会处理成默认值)//n = n || 0;//m = m || 0;/*回调函数执行*/typeof callback ==="function" ? callback() : null;
}
typeof undefined; //"undefined"typeof true; //"boolean"
typeof false; //"boolean"typeof 6; //"number"
typeof 6.5; //"number"
typeof NaN; //"number"typeof "LBJhui"; //"string"
typeof 'LBJhui'; //"string"hello = function(){};
typeof hello; //"function"typeof Symbol; //"function"
typeof new Function(); //"function"typeof []; //"object"
typeof {}; //"object"
typeof null; //"object"
typeof new Array(); //"object"
typeof new Object(); //"object"
typeof new Error(); //"object"
typeof new Number(); //"object"
typeof new String(); //"object"
typeof new Date(); //"object"
typeof new RegExp(); //"object"
返回一个小写字母的类型字符串
只需要一个操作数
简单数据类型或者函数或者对象
在 ECMAScript 2015 之前,typeof
总能保证对任何所给的操作数返回一个字符串。即便是没有声明的标识符,typeof
也能返回 'undefined'
。使用 typeof
永远不会抛出错误。
但在加入了块级作用域的 let
和 const 之后,在其被声明之前对块中的 let
和 const
变量使用 typeof
会抛出一个 ReferenceError。块作用域变量在块的头部处于“暂存死区”,直至其被初始化,在这期间,访问变量将会引发错误。
typeof undeclaredVariable === 'undefined';
typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceErrorlet newLetVariable;
const newConstVariable = 'hello';
class newClass{};
instanceof & constructor
/*
instanceof:本意是用来检测实例是否隶属于某个类的运算符,我们基于这样的方式,也可以用来做某些数据类型的检测,例如:数组、正则等
@局限性不能处理基本数据类型只要在当前实例的原型链(__proto__)中出现过的类,检测结果都是true(用户可能会手动修改原型链的指向:example.__proto__ 或者 在类的继承中 等情况)
*/
let arr[],reg = /^$/,obj = {};
arr instanceof Array; //true
reg instanceof Array; //false
arr instanceof Object; //true
obj instanceof Array; //false1 instanceof Number; //false
//创建值的两种方式(不管哪种方式都是所属于类的实例)
//字面量:let n = 12;
//构造函数:let m = new Number("12")function func(){argument instanceof Array; //falseargument.__proto__ = Array.prototypeargument instanceof Array; //true
}/*
constructor:构造函数
@原理:在类的原型上一般都会带有constructor属性,存储当前类本身,我们也是利用这一点,获取某类的实例constructor属性值,验证是否为所属的类,从而进行数据类型检测
@局限性:constructor属性值太容易被修改了
*/
let n = 12;
let arr = [];
n.constructor; //ƒ Number() { [native code] }
n.constructor === Number; //true
arr.constructor === Array; //true
arr.constructor === Object; //false
arr.constructor = 111;//设置私有属性
arr.constructor === Array; //false
Func.prototype = {}; //这样原型上没有constructor属性(重构了)
a = new Number(888);
a instanceof Number; //trueb = new String('LBJhui');
b instanceof String; //truec = new Array(6,66,666);
c instanceof Array; //trued = new Object();
d instanceof Object; //true"LBJhui" instanceof String; //false
888 instanceof Number; //false
true instanceof Boolean; //false[1,2] instanceof Array; //truevar person = {name:"LBJhui",gender:"male"};
person instanceof Object; //truenew Number(888) instanceof Number; //true
以上结果显示,直接的字面量值判断数据类型,只有引用数据类型(Array,Function,Object)被精准判断,其他(Number,Boolean,String)字面值不能被instanceof精准判断。
需要注意的是,如果表达式 obj instanceof Foo
返回 true
,则并不意味着该表达式会永远返回 true
,因为 Foo.prototype
属性的值有可能会改变,改变之后的值很有可能不存在于 obj
的原型链上,这时原表达式的值就会成为 false
。另外一种情况下,原表达式的值也会改变,就是改变对象 obj
的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__
伪属性,是可以实现的。比如执行 obj.__proto__ = {}
之后,obj instanceof Foo
就会返回 false
了。
instanceof来判断null和undefined,浏览器在这里报错了,它认为null,undefined不是构造器。
… | typeof | instanceof |
---|---|---|
作用 | 检测数据类型 | 检测对象之间的关联性 |
返回 | 小写字母字符串 | 布尔值 |
操作数 | 简单数据类型、函数或者对象 | 左边必须是引用类型,右边必须是函数 |
操作数个数 | 1个 | 2个 |
Object.prototype.toString.call([value])
/*
Object.prototype.toString.call([value]):调用Object原型上的toString方法,让方法执行的时候,方法中的this是要检测的数据类型,从而获取到数据类型所属类的详细信息
toString() 方法返回一个表示该对象的字符串。
@信息的模板"[object 所属类]",例如:"[object Array]"
在所有的数据类型类中,它们的原型上都有toString方法,除Object.prototype.toString不是把数据值转换为字符串,其余的都是转换为字符串,而Object原型上的toString是检测当前实例隶属类的详细信息的(检测数据类型)obj.toString()1.首先基于原型链查找机制,找到Object.prototype.toString2.把找到的方法执行,方法中的this->obj3.方法内部把this(obj)的所属类信息输出=>方法执行,方法中的this是谁,就是检测谁的所属类信息
这个方法很强大, 所有数据类型隶属于的类信息检测的一清二楚
Number/String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Data/Math/Function...
*/
[12,23].toString(); //"12,23"
/^\d+$/.toString(); //"/^\d+$/"
(function anonymous(){}).toString(); //"function anonymous(){}"let obj1 = {},obj2 = {name:"LBJhui"}
obj1.toString(); //"[object Object]"
obj2.toString(); //"[object Object]"let obj = {};
obj.toString.call(100) //"[object Number]"
Object.prototype.toString.call(100) //"[object Number]"let _obj ={};
toString = _obj.toString;
toString.call();
每个对象都有一个 toString()
方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString()
方法被每个 Object
对象继承。如果此方法在自定义对象中未被覆盖,toString()
返回 “[object type]”,其中 type
是对象的类型。以下代码说明了这一点:
var o = new Object();
o.toString(); // returns [object Object]
可以通过 toString()
来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString()
来检测,需要以 Function.prototype.call()
或者 Function.prototype.apply()
的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg
。
var toString = Object.prototype.toString;
toString.call(333); // [object Number]
toString.call("aaa"); // [object String]
toString.call(true); // [object Boolean]
toString.call([]); // [object Array]
toString.call(function(){}); // [object Function]
toString.call({}); // [object Object]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]// 甚至于js的内置对象也能被精确判断
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
封装一个数据类型检测的方法库
let _obj = {isNumeric:"Number",isBoolean:"Boolean",isString:"String",isNull:"Null",isUndefined:"Undefined",isSymbol:"Symbol",isPlainObject:"Object",isArray:"Array",isRegExp:"RegExp",isDate:"Date",isFunction:"Function",isWindow:"Window"
},
_toString.call(val) = _obj.toString;
_type = {};
for(let key in _obj){if(!_obj.hasOwnProperty(key)) break;//key =isNumeric//_obj[key]="Number"//val=12let reg = new RegExp("\\[Object" + _obj[key] + "\\]");_type[key] = function anonymous(val){return reg.test(_toString.call(val));}
}
JavaScript中的数据类型检测原理相关推荐
- 前端系统化学习【JS篇】:(四)Javascript中的数据类型
前言 细阅此文章大概需要 3分钟\color{red}{3分钟}3分钟左右 本篇中简述\color{red}{简述}简述了: Javascript中常用的数据类型 基本数据类型 引用数据类型 数据类型 ...
- html类型转换函数,如何在JavaScript中转换数据类型?
在JavaScript中,数据类型用于对一种特定类型的数据进行分类,确定可以分配给类型的值以及可以对其执行的操作.虽然由于类型强制,JavaScript会自动转换许多值,但为了达到预期的结果,通常最好 ...
- 科普向--详解JavaScript中的数据类型
对于前端的小伙伴而言,JS的数据类型可谓是必懂的知识点.虽然这个知识点很是基础了,不过仍然有不少人会在这一块犯些小错误.比如网上流传的"JavaScriptS一切皆对象",其实是个 ...
- JavaScript中函数式编程的原理
要了解JavaScript中的函数式编程原理,必须理解一下两个知识点: 1,JavaScript中函数.方法的调用 在JavaScript中,有两种调用函数的方式.一般的方式是把参数放在括号中,另一种 ...
- JavaScript中基本数据类型的强制转换
JavaScript中基本数据类型转化 将一个数据类型强制转换为其他的数据类型 主要指String Number Boolean 这三种之间的相互转化. 一.其他数据类型转换String 我们有两种方 ...
- JavaScript中的数据类型判断
typeof typeof 操作符返回一个字符串,表示未经计算的操作数的类型. 语法 typeof 运算符后接操作数: typeof operand typeof(operand) 参数 operan ...
- javaScript中判断数据类型的方法
目录 一.javaScript数据类型 二.javaScript判断数据类型的方法 1.使用typeof 2.使用instanceof 3.使用Object.prototype.toString.ca ...
- javascript中this的工作原理以及注意事项
在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this ...
- js中各种数据类型检测与判定
介绍 在前端开发中,js 有各种各样的数据类型,数据类型检测是每个开发者都必须掌握基础知识.数据类型检测的方法也有很多种,本题将封装一个通用的数据类型检测函数. 准备 本题已经内置了初始代码,打开实验 ...
最新文章
- vue.js中请求数据v-for循环使用数据
- 实施ITIL十个需要知道的事情
- hadoop学习1 java操作HDFS
- vue中created钩子函数与mounted钩子函数的使用区别
- 计算指定年月的最后一天的自定义函数
- 巧用tab组件实现APP的布局效果
- Excel中 ColorIndex 属性值和颜色对照表
- 数据结构与算法14-栈和队列练习题
- 树莓派 无法定位软件包 解决方案
- 知其然知其所以然 itoa实现 整型转字符串
- 春季高考计算机专业知识归纳,春季高考计算机试题总结分析
- PHPMailer 使用方法(支持群发):
- systemd service unit
- 使用DISM启用或禁用Windows功能
- 照明开关雷达感应方案,多普勒雷达模块技术,智能雷达感控应用
- 某徒步旅游网站python爬虫小练习
- Docker安装Weblogic
- opencv学习笔记(八)-- 在图像上绘制形状和文字
- React路由跳转时通过传参进行动态渲染的方法
- 鸿蒙之境法有三乘,神都夜行录鸿蒙之境八百流沙详细打法攻略