JavaScript数据类型判断的四种方法
码文不易啊,转载请带上本文链接呀,感谢感谢 https://www.cnblogs.com/echoyya/p/14416375.html
本文分享了JavaScript类型判断的四种方法:typeof、instanceof、Object.prototype.toString.call()、constructor
JavaScript数据类型
JavaScript有八种内置类型,除对象外,其他统称为基本类型
空值(null)
未定义(undefined)
布尔值(boolean)
数字(number)
字符串(string)
对象 (object)
符号(symbol, ES6中新增)
大整数(BigInt, ES2020 引入)
Symbol: 是ES6中引入的一种原始数据类型,表示独一无二的值。
BigInt:是 ES2020 引入的一种新的数据类型,用来解决 JavaScript中数字只能到 53 个二进制位(JavaScript 所有数字都保存成 64 位浮点数,大于这个范围的整数,无法精确表示的问题。具体可查看:新数据类型 — BigInt
一、typeof
typeof是一个操作符而不是函数,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示
包括以下 8 种:string、number、boolean、undefined、function 、symbol、bigInt、object。
对于数组,对象,null以及时间等数据,typeof只能返回object,而不能直接返回对应的类型,还需要通过其他法判断。
console.log(typeof ""); // string
console.log(typeof 1 ); // number
console.log(typeof NaN ); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof function(){}); // function
console.log(typeof isNaN); // function
console.log(typeof Symbol()); // symbol
console.log(typeof 123n); // bigint
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object
console.log(typeof new Date()); // object
console.log(typeof new RegExp()); // object
二、instanceof
instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 需特别注意:instanceof 检测的是原型
即instanceof 用来比较一个对象是否为某一个构造函数的实例。instanceof可以准确的判断复杂数据类型,但是不能正确判断基本数据类型
console.log(12 instanceof Number); // false
console.log('22' instanceof String); // false
console.log(true instanceof Boolean); // false
console.log(null instanceof Object); // false
console.log(undefined instanceof Object); // false
console.log(function a() {} instanceof Function); // true
console.log([] instanceof Array); // true
console.log({a: 1} instanceof Object); // true
console.log(new Date() instanceof Date); // true
三、constructor
- JavaScript中,每个对象都有一个constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的, constructor属性表示原型对象与构造函数之间的关联关系。
当一个函数F被定义时,JS引擎会为F添加prototype原型,然后在prototype上添加一个constructor属性,并让其指向F的引用,F利用原型对象的constructor属性引用了自身,当F作为构造函数创建对象时,原型上的constructor属性被遗传到了新创建的对象上,从原型链角度讲,构造函数F就是新对象的类型。这样做的意义是,让对象诞生以后,就具有可追溯的数据类型。
通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。
如判断数组的函数:
function isArray(data){
return typeof data == "object" && data.constructor == Array;
}
isArray([]) // true
注意:null 和 undefined 是没有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
console.log('22'.constructor === String) // true
console.log(true.constructor === Boolean) // true
console.log([].constructor === Array) // true
console.log(document.constructor === HTMLDocument) // true
console.log(window.constructor === Window) // true
console.log(new Number(22).constructor === Number) // true
console.log(new Function().constructor === Function) // true
console.log(new Date().constructor === Date) // true
console.log(new RegExp().constructor === RegExp) // true
console.log(new Error().constructor === Error) // true
- 如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,一般要同时修改constructor属性的指向。
function Rectangle(width, height){
this.width = width;
this.height = height;
this.getArea = function(){
return '矩形的面积为' + (width * height);
}
}
var rect1 = new Rectangle(40, 20);
var rect2 = new Rectangle(50, 20);
var rect3 = new Rectangle(60, 20);
console.log(rect1.getArea());
console.log(rect2.getArea());
console.log(rect3.getArea());
如上代码,每次实例化出一个对象,都会添加getArea方法,是三个对象共有且不变的,因此将getArea放在构造函数中就会在创建对象时被多次添加,浪费内存!
因此我们将getArea添加到原型对象上就减少了多次添加,实例化对象会沿着原型链查找到此属性
实现了共享属性:
function Rectangle(width, height){
this.width = width;
this.height = height;
}
// 直接替换原型对象,但是要记得添加上构造函数属性
Rectangle.prototype = {
constructor: Rectangle,
getArea: function(){
return '矩形的面积为' + (this.width * this.height);
}
}
// 修改特性
Object.defineProperties(Rectangle.prototype, {
constructor: {
enumerable: false,
configurable: false,
writable: false
},
getArea: {
enumerable: false,
configurable: false,
writable: false
}
})
var rect1 = new Rectangle(40, 20);
var rect2 = new Rectangle(50, 20);
var rect3 = new Rectangle(60, 20);
console.log(rect1.getArea());
console.log(rect2.getArea());
console.log(rect3.getArea());
- 很多情况下,我们可以使用instanceof运算符或对象的constructor属性来检测对象是否为数组。如很多JS框架就是使用这两种方法来判断对象是否为数组类型。 但是检测在跨框架(cross-frame)页面中的数组时,会失败。原因就是在不同框架(iframe)中创建的数组不会相互共享其prototype属性。例如:
<script>
window.onload=function(){
var iframe_arr=new window.frames[0].Array;
console.log(iframe_arr instanceof Array); // false
console.log(iframe_arr.constructor == Array); // false
}
</script>
四、Object.prototype.toString.call()
Object.prototype.toString(o)是 Object 的原型方法,获取对象o的class属性。这是一个内部属性,
连接字符串:[object + 结果(1)],格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
console.log(Object.prototype.toString.call(1)) // [object Number]
console.log(Object.prototype.toString.call(1n)) // [object BigInt]
console.log(Object.prototype.toString.call('123')) // [object String]
console.log(Object.prototype.toString.call(true)) // [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({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(function a() {})) // [object Function]
console.log(Object.prototype.toString.call(Symbol())) // [object Symbol]
console.log(Object.prototype.toString.call(Math)) // [object Math]
console.log(Object.prototype.toString.call(JSON)) // [object JSON]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(new RegExp())) // [object RegExp]
console.log(Object.prototype.toString.call(new Error)) // [object Error]
console.log(Object.prototype.toString.call(window) // [object Window]
console.log(Object.prototype.toString.call(document)) // [object HTMLDocument]
- 封装一个准确判断数据类型的函数
function __getType(object){
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
};
- 可以解决上面的跨框架问题。
<script>
window.onload=function(){
var iframe_arr=new window.frames[0].Array;
console.log(Object.prototype.toString.call(iframe_arr))) // "[object Array]"
}
</script>
JavaScript数据类型判断的四种方法的更多相关文章
- (转)javascript异步编程的四种方法
本文转自:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 作者:阮一峰 本文仅仅作为个人mark ...
- Js中数据类型判断的几种方法
判断js中的数据类型有一下几种方法:typeof.instanceof. constructor. prototype. $.type()/jquery.type(),接下来主要比较一下这几种方法的异 ...
- JavaScript数组去重的四种方法
今天,洗澡的想一个有趣的问题,使用js给数组去重,我想了四种方法,虽然今天的任务没有完成,5555: 不多说,po代码: //方法一:简单循环去重 Array.prototype.unique1 ...
- JS数据类型判断的几种方法
JS数据类型判断 JavaScript 中常见数据类型有Number.String.Boolean.Object.Array.Json.Function.Date.RegExp.Error.undef ...
- JavaScript异步编程的四种方法
1.回调函数 f1(f2); 回调函数是异步编程的基本方法.其优点是易编写.易理解和易部署:缺点是不利于代码的阅读和维护,各个部分之间高度耦合 (Coupling),流程比较混乱,而且每个任务只能指定 ...
- js,javascript生成 UUID的四种方法
全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度 ...
- 判断数组的方法/判断JS数据类型的四种方法
参考文: 以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() . instanceof 以及 Array.isArray() h ...
- 判断js数据类型的四种方法,以及各自的优缺点(转)
转载地址:https://blog.csdn.net/lhjuejiang/article/details/79623973 数据类型分为基本类型和引用类型: 基本类型:String.Number.B ...
- js中判断数据类型的四种方法总结
js中判断数据类型的四种方法 前言 在js中,我们经常需要判断数据的类型,那么哪些方法可以用来判断数据的类型呢?哪种方法判断数据类型最准确呢? 我们来一个个分析: 1.typeof typeof是一个 ...
随机推荐
- Android第一代壳demo编写
Android第一代壳Demo编写 前言 这篇文章是对姜维大佬的这篇文章[Android中的Apk的加固(加壳)原理解析和实现]的补充.建议先看一编姜维大佬的这篇文章再看. 姜维大佬写那篇文章的时间距 ...
- 希尔伯特曲线python3实现
需要OpenGL库:https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl #coding:utf-8 from OpenGL.GL import * ...
- linux 用户、用户组及相关命令(useradd 、passwd、userdel 、groupadd 、groupdel、usermod 、gpasswd 、 id、su)
linux是一个多用户系统,用于权限管理(权限最小化); 相关命令: 7 8 9 10 11 12 13 14 15 useradd passwd userdel groupadd groupdel ...
- [POJ 2585] Window Pains 拓朴排序
题意:你现在有9个2*2的窗口在4*4的屏幕上面,由于这9这小窗口叠放顺序不固定,所以在4*4屏幕上有些窗口只会露出来一部分. 如果电脑坏了的话,那么那个屏幕上的各小窗口叠放会出现错误.你的任务就是判 ...
- hdu2546 饭卡
Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负) ...
- kafka消息队列、环境搭建与使用(.net framework)
一:kafka介绍 kafka(官网地址:http://kafka.apache.org)是一种高吞吐量的分布式发布订阅的消息队列系统,具有高性能和高吞吐率. 1.1 术语介绍 BrokerKafka ...
- @Indexed 注解
本文转载自:https://www.cnblogs.com/aflyun/p/11992101.html 最近在看 SpringBoot 核编程思想(核心篇),看到走向注解驱动编程这章,里面有讲解到: ...
- 数理统计9:完备统计量,指数族,充分完备统计量法,CR不等式
昨天我们给出了统计量是UMVUE的一个必要条件:它是充分统计量的函数,且是无偏估计,但这并非充分条件.如果说一个统计量的无偏估计函数一定是UMVUE,那么它还应当具有完备性的条件,这就是我们今天将探讨 ...
- 在.NET中体验GraphQL
前言 以前需要提供Web服务接口的时候,除了标准的WEBAPI形式,还考虑了OData.GraphQL等形式,虽然实现思路上有很大的区别,但对使用方来说,都是将查询的主动权让渡给了前端,让调用方能够更 ...
- 【转】Docker 核心技术与实现原理
转自:https://draveness.me/docker 提到虚拟化技术,我们首先想到的一定是 Docker,经过四年的快速发展 Docker 已经成为了很多公司的标配,也不再是一个只能在开发阶段 ...