JavaScript 判断数据类型的方法
文章目录
- 1、javascript 中的数据类型
- 2、`typeof` 返回 变量的数据类型
- 3、`instanceof ` :复杂数据类型的判断
- 3.1、instanceof 原理分析(初学者跳过)
- 3.2、使用示例
- 4、使用 `Object.prototype.toString.call` (最准确的判断类型)
- 4.1、例子
- 5、使用 `constructor`
- 5.1、原理分析(初学者跳过)
- 5.2、细节问题(初学者跳过)
- 5.3、使用例子
- 6、jQuery 中判断数据类型的方法
1、javascript 中的数据类型
在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示:
基本类型:String、Number、Boolean、Symbol、Undefined、Null
引用类型:Object、Function 、Array、RegExp、Date
基本类型
,也称为 简单类型
,由于其占据空间固定,是简单的数据段,为了便于提升变量查询速度,将其存储在栈中,即按值访问。
引用类型
,也称为 复杂类型
,由于其值的大小会改变,所以不能将其存放在栈中,否则会降低变量查询速度,因此,其值存储在堆(heap)中,而存储在变量处的值,是一个指针,指向存储对象的内存处,即按址访问。
引用类型除 Object 外,还包括 Function 、Array、RegExp、Date
等等。
2、typeof
返回 变量的数据类型
typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。
返回的结果用该类型的字符串(全小写字母)形式表示,共 7 种。
numbe、stringr、boolean、undefined、function、object、symbol 等。
示例:
let obj={name:'dawn',age:21
};let myFun = function() {console.log('我是 function 类型');
};console.log(typeof myFun); //function
console.log(typeof 1); //number
console.log(typeof 'abc'); //string
console.log(typeof true); //boolean
console.log(typeof undefined); //undefined// 下面这此,typeof 只有测出为 object,不能进一步判断它们的类型
console.log(typeof obj); // object
console.log(typeof null); //object ,无法准确测出是 null
console.log(typeof (new Date) ); //object ,无法准确测出是 日期类型
console.log(typeof [1,2,3]); //object ,无法准确测出是 数组
console.log(typeof (new RegExp())); //object ,无法准确测出是 RegExp类型
说明:
typeof
可以准确测试出 number、string、boolean、undefined、function, 共5种数据类型。对象、null、数组、Date、Array数组等类型,
typeof
只能测出为object,不能进一步判断它们的类型。
总结:
- 对于基本类型,除 null 以外,均可以返回正确的结果。
- 对于引用类型,除 function 以外,一律返回 object 类型。
- 对于 null ,返回 object 类型。
- 对于 function 返回 function 类型。
3、instanceof
:复杂数据类型的判断
obj instanceof Object
:左边是 要判断的内容,右边是类型,判断 obj 是否为 Object 的实例 。
instanceof
注意事项:
只能用来判断 复杂数据类型 ,因为
instanceof
是用于检测构造函数(右边)的 prototype 属性是否出现在某个实例对象(左边)的原型链上。基本数据类型,不能用 instanceof 判断类型;
基本数据包装类创建的 对象 可以用 instanceof 判断;
undefined 和 null 没有构造函数,所以使用 instanceof 会报错;
例子:
3.1、instanceof 原理分析(初学者跳过)
instanceof 检测的是 原型,我们用一段伪代码来模拟其内部执行过程:
instanceof (A,B) = {var L = A.__proto__;var R = B.prototype;if(L === R) {// A的内部属性 __proto__ 指向 B 的原型对象return true;}return false;
}
从上述过程可以看出,当 A 的 proto 指向 B 的 prototype 时,就认为 A 就是 B 的实例。
我们再来看几个例子,
console.log([] instanceof Array); // true
console.log({} instanceof Object);// true
console.log(new Date() instanceof Date); // truefunction Person(){};
console.log(new Person() instanceof Person); // true
//上面的4种判断为true,应该都能理解//下面这3个判断也为true, 大家可能会疑问
console.log([] instanceof Object); // true
console.log(new Date() instanceof Object);// true
console.log(new Person instanceof Object);// true
上面的例子中, instanceof 能够判断出 [ ] 是Array的实例,但它认为 [ ] 也是Object的实例,为什么呢?
我们来分析一下 [ ]、Array、Object
三者之间的关系:
通过上面的图 ,instanceof
能够判断出 [ ].__proto__
指向 Array.prototype
,
而 Array.prototype.__proto__
又指向 Object.prototype
,
最终, Object.prototype.__proto__
指向了 null ,标志着原型链的结束。
因此,[]、Array、Object
就在内部形成了一条原型链。
instanceof
操作符的问题在于,它假定只有一个全局执行环境。如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[0].Array;
var arr = new xArray(1,2,3); // [1,2,3]
console.log(arr instanceof Array); // false
针对数组的这个问题,ES5 提供了 Array.isArray()
方法 。该方法用以确认某个对象本身是否为 Array 类型,而不区分该对象在哪个环境中创建。
if(Array.isArray(value)){//对数组执行某些操作
}
Array.isArray()
本质上检测的是对象的 [[Class]]
值,
[[Class]]
是对象的一个内部属性,里面包含了对象的类型信息,其格式为 [object Xxx]
,Xxx
就是对应的具体类型 。
对于数组而言,[[Class]]
的值就是 [object Array]
。
3.2、使用示例
let arr=[1,2,3,4,5,6,7];
let obj={name:'zhangsan',age:21
};
let myfun=function() {console.log('我是 function 类型');
};;console.log(arr instanceof Array); //true
console.log(obj instanceof Object); //true
console.log(myfun instanceof Function); //trueconsole.log((new Date) instanceof Date); //true
4、使用 Object.prototype.toString.call
(最准确的判断类型)
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]]
。这是一个内部属性,其格式为 [object Xxx]
,其中 , Xxx
就是对象的类型。
对于 Object 对象,直接调用 toString()
就能返回 [object Object]
。而对于其他对象,则需要通过 call / apply
来调用才能返回正确的类型信息。
从实例我们可以看出该方法能判断基本类型,也能判断 Array 和 Function。
对于Object对象:
实例可见,对于Object对象,可以直接使用 toString() 方法,对于其他内置对象,Object.prototype.toString.call()
方法都能准确的判断出其类型。
结论:
Object.prototype.toString.call()
方法是判断类型的最准确的方法!
4.1、例子
简化:
Object.prototype.toString.call(obj) 简化为 toString.call(obj)
示例:
let obj = {name: 'dawn',age: 21
};
let myfun = function () {console.log('我是 function 类型');
};console.log(toString.call(obj)); // [object Object]
console.log(toString.call(myfun)); // [object Function]console.log(toString.call(1)); // [object Number]
console.log(toString.call('Hello tomorrow')); // [object String ]
console.log(toString.call(true)); // [object Boolean]
console.log(toString.call(undefined)); // [object Undefined]console.log(toString.call(new Date)); // [object Date]
console.log(toString.call(null)); // [object Null]
console.log(toString.call([1, 2, 3])); // [object Array]
5、使用 constructor
5.1、原理分析(初学者跳过)
当一个函数 F
被定义时,JavaScript 引擎会为 F
添加 prototype
原型,然后再在 prototype
上添加一个 constructor
属性,并让其指向 F
的引用。如下所示:
当执行 var f = new F()
时,F
被当成了构造函数,f
是 F
的实例对象,此时 F
原型上的 constructor
传递到了 f
上,因此 f.constructor == F
。
可以看出,F
利用原型对象上的 constructor
引用了自身,当 F
作为构造函数来创建对象时,原型上的 constructor
就被遗传到了新创建的对象上, 从原型链角度讲,构造函数 F
就是新对象的类型。这样做的意义是,让新对象在诞生以后,就具有可追溯的数据类型。
同样,JavaScript 中的内置对象在内部构建时也是这样做的:
5.2、细节问题(初学者跳过)
1、null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
2、 函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object 。
为什么变成了 Object?
因为 prototype 被重新赋值的是一个 { }, { } 是 new Object() 的字面量,因此 new Object() 会将 Object 原型上的 constructor 传递给 { },也就是 Object 本身。
因此,为了规范开发,在重写对象原型时一般都需要重新给 constructor 赋值,以保证对象实例的类型不被篡改。
5.3、使用例子
let arr = [1, 2, 3, 4, 5, 6, 7]
let obj = {name: 'dawn',age: 21
};
let fn = function () {console.log('我是 function 类型');
};console.log((9).constructor === Number); //true
console.log('hello'.constructor === String); //true
console.log(true.constructor === Boolean); //true
console.log(fn.constructor === Function); //true
console.log((new Date).constructor === Date); //true
console.log(obj.constructor === Object); //true
console.log([1, 2, 3].constructor === Array); //true
注意:
constructor
不能判断 undefined
和 null
,并且使用它是不安全的,因为 contructor 的指向是可以改变的
6、jQuery 中判断数据类型的方法
jQuery 提供了一系列工具方法,用来判断数据类型,以弥补 JavaScript 原生的 typeof 运算符的不足。
以下方法对参数进行判断,返回一个布尔值。
jQuery.isArray(); // 是否为数组
jQuery.isEmptyObject(); // 是否为空对象 (不含可枚举属性)。
jQuery.isFunction(); // 是否为函数
jQuery.isNumberic(); // 是否为数字
jQuery.isPlainObject(): // 是否为使用“{}”或“new Object”生成对象,而不是浏览器原生提供的对象。
jQuery.isWindow(); // 是否为window对象;
jQuery.isXMLDoc(); // 判断一个DOM节点是否处于XML文档中。
JavaScript 判断数据类型的方法相关推荐
- JavaScript判断数据类型的方法
JavaScript判断数据类型的方法 1 数据类型有哪些? 2 判断JavaScript数据类型的方法 2.1 typeof 2.2 instanceof 2.3 constructor 2.4 t ...
- javaScript中判断数据类型的方法
目录 一.javaScript数据类型 二.javaScript判断数据类型的方法 1.使用typeof 2.使用instanceof 3.使用Object.prototype.toString.ca ...
- js中判断数据类型的方法
JS中判断数据类型的方法: 使用typeof操作符. 对一个值使用 typeof 操作符可能返回下列某个字符串,返回的类型都是字符串形式. (1) undefined:如果这个值未定义 (2) boo ...
- JavaScript判断数据类型的方式
JavaScript判断数据类型的方式 js中的数据类型有哪些? 基本数据类型:number.string.boolean.null.undefined.symbol以及未来ES10新增的BigInt ...
- JavaScript 判断数据类型
JavaScript 判断数据类型 首先JavaScript基本数据类型有:number null undefined string boolean es6以后还新增了bigint和symbol (上 ...
- python判断数据_python判断数据类型的方法
python判断数据类型的方法 发布时间:2020-08-19 15:23:59 来源:亿速云 阅读:96 作者:小新 小编给大家分享一下python判断数据类型的方法,相信大部分人都还不怎么了解,因 ...
- 分享一波很全的 JS 判断数据类型的方法
分享一波很全的 JS 判断数据类型的方法 干货满满,很常用也很有用的一波方法整理,分享给需要的小伙伴们. 偷偷说一句,小肉包之前整理的没有这么简洁和全面,后面小肉包的男朋友又帮忙加工润色了一下,现在看 ...
- JavaScript判断数据类型是不是数组
JavaScript判断数据类型是不是数组 1.Array.isArray(es6 新增) 在这里插入代码片 Array.isArray([]) true Array.isArray({}) fals ...
- javascript 判断数据类型的几种方法 1
1.typeof 类型判断 缺点:无法区分null .对象.数组,Map,Set,WeakMap,WeakSet.RegExp等 注意:通过构造函数创建的变量typeof 后是都是object var ...
最新文章
- 苗旺:因果推断,观察性研究和 2021 年诺贝尔经济学奖
- 解决Chrome浏览器打开虾米音乐网页播放器时的排版问题
- python 去除字符串的标点符号 用_7步搞定数据清洗-Python数据清洗指南
- JavaOne 2012:101种改进Java的方法-开发人员参与为何如此重要
- WinDbg 查看静态变量
- 对话阿里敏捷教练 | 成功辅导过淘宝、闲鱼,他都是如何帮助团队
- java 生成素数_java – 素数生成器逻辑
- VINS-Mono代码分析与总结(完整版)
- 在JavaWeb中,什么是监听器?(建议收藏)
- 6.表单提交,input键盘变搜索,有关自定义属性input操作
- 串口屏还是并口屏好用?
- 跨平台显示MMD模型
- Caused by: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.and
- AVR单片机的BOOT区
- nvidia jetson agx xavier运行 OpenCL
- INS/GNSS组合导航(六)-惯性器件的主要误差
- 计算机组装小白,小白怎么从零开始学组装电脑?
- 后处理之TCL语言教程
- 教你彻底学会动态规划——进阶篇
- 华为云Astro的前世今生:用7年时间革新低代码开发观念