js php 数据类型判断,【js基础】变量类型判断

类型判断方法比较:

0f44efd182a11c91c2b1ad55340f8e5f.png

如果需要想详细了解,请看下文:

注:原封不动复制备份,防止删帖

在JavaScript中,有5种基本数据类型和1种复杂数据类型,基本数据类型有:Undefined, Null, Boolean, Number和String;复杂数据类型是Object, Object中还细分了很多具体的类型,比如:Array, Function, Date等等。今天我们就来探讨一下,使用什么方法判断一个出一个变量的类型。

在讲解各种方法之前,我们首先定义出几个测试变量,看看后面的方法究竟能把变量的类型解析成什么样子,以下几个变量差不多包含了我们在实际编码中常用的类型。var num = 123;

var str = ‘abcdef’;

var bool = true;

var arr = [1, 2, 3, 4];

var json = {name:’wenzi’, age:25};

var func = function(){ console.log(‘this is function’); }

var und = undefined;

var nul = null;

var date = new Date();

var reg = /^[a-zA-Z]{5,20}$/;

var error= new Error();

1. 使用typeof检测

我们平时用的最多的就是用 typeof检测变量类型了。这次,我们也使用 typeof检测变量的类型:console.log(

typeof num,

typeof str,

typeof bool,

typeof arr,

typeof json,

typeof func,

typeof und,

typeof nul,

typeof date,

typeof reg,

typeof error

);

// number string boolean object object function undefined object object object object

从输出的结果来看,arr, json, nul, date, reg, error 全部被检测为 object类型,其他的变量能够被正确检测出来。当需要变量是否是 number, string, boolean, function, undefined, json类型时,可以使用typeof进行判断。其他变量是判断不出类型的,包括null。

还有,typeof是区分不出 array和 json类型的。因为使用typeof这个变量时,array和json类型输出的都是 object。使用instance检测

在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:function Person(){

} var Tom = new Person(); console.log(Tom instanceof Person); // true

我们再看看下面的例子:function Person(){

} function Student(){

} Student.prototype = new Person(); var John = new Student(); console.log(John instanceof Student); // true console.log(John instancdof Person); // true instanceof还能检测出多层继承的关系。

好了,我们来使用 instanceof检测上面的那些变量:

console.log(

num instanceof Number,

str instanceof String,

bool instanceof Boolean,

arr instanceof Array,

json instanceof Object,

func instanceof Function,

und instanceof Object,

nul instanceof Object,

date instanceof Date,

reg instanceof RegExp,

error instanceof Error ) // num : false // str : false // bool : false // arr : true // json : true // func : true // und : false // nul : false // date : true // reg : true // error : true

从上面的运行结果我们可以看到,num, str和bool没有检测出他的类型,但是我们使用下面的方式创建num,是可以检测出类型的:var num = new Number(123);

var str = new String(‘abcdef’);

var boolean = new Boolean(true);

同时,我们也要看到,und和nul是检测的Object类型,才输出的true,因为js中没有 Undefined和 Null的这种全局类型,他们und和nul都属于Object类型,因此输出了true。使用constructor检测

在使用 instanceof检测变量类型时,我们是检测不到 number, ‘string’, bool的类型的。因此,我们需要换一种方式来解决这个问题。

constructor本来是原型对象上的属性,指向构造函数。但是根据实例对象寻找属性的顺序,若实例对象上没有实例属性或方法时,就去原型链上寻找,因此,实例对象也是能使用constructor属性的。

我们先来输出一下 num.constructor的内容,即数字类型的变量的构造函数是什么样子的:

function Number() { [native code] }

我们可以看到它指向了 Number的构造函数,因此,我们可以使用 num.constructor==Number来判断num是不是Number类型的,其他的变量也类似:function Person(){

} var Tom = new Person();

// undefined和null没有constructor属性 console.log(

Tom.constructor==Person,

num.constructor==Number,

str.constructor==String,

bool.constructor==Boolean,

arr.constructor==Array,

json.constructor==Object,

func.constructor==Function,

date.constructor==Date,

reg.constructor==RegExp,

error.constructor==Error );

// 所有结果均为true

从输出的结果我们可以看出,除了undefined和null,其他类型的变量均能使用 constructor判断出类型。

不过使用constructor也不是保险的,因为constructor属性是可以被修改的,会导致检测出的结果不正确,例如:function Person(){

} function Student(){

} Student.prototype = new Person(); var John = new Student(); console.log(John.constructor==Student); // false console.log(John.constructor==Person); // true

在上面的例子中,Student原型中的constructor被修改为指向到Person,导致检测不出实例对象John真实的构造函数。

同时,使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false;

原因:

1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。

2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!使用Object.prototype.toString.call

我们先不管这个是什么,先来看看他是怎么检测变量类型的:console.log(

Object.prototype.toString.call(num),

Object.prototype.toString.call(str),

Object.prototype.toString.call(bool),

Object.prototype.toString.call(arr),

Object.prototype.toString.call(json),

Object.prototype.toString.call(func),

Object.prototype.toString.call(und),

Object.prototype.toString.call(nul),

Object.prototype.toString.call(date),

Object.prototype.toString.call(reg),

Object.prototype.toString.call(error)

);

// ‘[object Number]’ ‘[object String]’ ‘[object Boolean]’ ‘[object Array]’ ‘[object Object]’

// ‘[object Function]’ ‘[object Undefined]’ ‘[object Null]’ ‘[object Date]’ ‘[object RegExp]’ ‘[object Error]’

从输出的结果来看, Object.prototype.toString.call(变量)输出的是一个字符串,字符串里有一个数组,第一个参数是Object,第二个参数就是这个变量的类型,而且,所有变量的类型都检测出来了,我们只需要取出第二个参数即可。或者可以使用 Object.prototype.toString.call(arr)==”object Array”来检测变量arr是不是数组。

我们现在再来看看ECMA里是是怎么定义 Object.prototype.toString.call的:

Object.prototype.toString( ) When the toString method is called, the following steps are taken:

1. Get the [[Class]] property of this object.

2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.

3. Return Result (2)

上面的规范定义了Object.prototype.toString的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于”[object Array]”的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。jquery中

.type的接口,来让我们检测变量的类型:console.log(

.type(str),

.type(arr),

.type(func),

.type(nul),

.type(reg),

$.type(error) );

// number string boolean array object function undefined null date regexp error

看到输出结果,有没有一种熟悉的感觉?对,他就是上面使用 Object.prototype.toString.call(变量)输出的结果的第二个参数呀。

我们这里先来对比一下上面所有方法检测出的结果,横排是使用的检测方法, 竖排是各个变量:

类型判断 typeof instanceof constructor toString.call

type输出的结果真的很像。我们来看看jquery(2.1.2版本)内部是怎么实现$.type方法的:

// 实例对象是能直接使用原型链上的方法的 var class2type = {}; var toString = class2type.toString;

// 省略部分代码…

type: function( obj ) {

if ( obj == null ) {

return obj + “”;

}

// Support: Android<4.0, iOS<6 (functionish RegExp)

return (typeof obj === “object” || typeof obj === “function”) ?

(class2type[ toString.call(obj) ] || “object”) :

typeof obj; },

// 省略部分代码…

// Populate the class2type map jQuery.each(“Boolean Number String Function Array Date RegExp Object Error”.split(” “), function(i, name) {

class2type[ “[object ” + name + “]” ] = name.toLowerCase(); });

我们先来看看jQuery.each的这部分:

// Populate the class2type map

jQuery.each(“Boolean Number String Function Array Date RegExp Object Error”.split(” “), function(i, name) {

class2type[ “[object ” + name + “]” ] = name.toLowerCase();

});

//循环之后,class2type的值是:class2type = {

‘[object Boolean]’ : ‘boolean’,

‘[object Number]’ : ‘number’,

‘[object String]’ : ‘string’,

‘[object Function]’: ‘function’,

‘[object Array]’ : ‘array’,

‘[object Date]’ : ‘date’,

‘[object RegExp]’ : ‘regExp’,

‘[object Object]’ : ‘object’,

‘[object Error]’ : ‘error’

}

再来看看 type方法:// type的实现

type: function( obj ) {

// 若传入的是null或undefined,则直接返回这个对象的字符串

// 即若传入的对象obj是undefined,则返回”undefined”

if ( obj == null ) {

return obj + “”;

}

// Support: Android<4.0, iOS<6 (functionish RegExp)

// 低版本regExp返回function类型;高版本已修正,返回object类型

// 若使用typeof检测出的obj类型是object或function,则返回class2type的值,否则返回typeof检测的类型

return (typeof obj === “object” || typeof obj === “function”) ?

(class2type[ toString.call(obj) ] || “object”) :

typeof obj;

}

当 typeof obj === “object” || typeof obj === “function”时,就返回 class2type[ toString.call(obj)。到这儿,我们就应该明白为什么Object.prototype.toString.call和$.type那么像了吧,其实jquery中就是用 Object.prototype.toString.call实现的,把’[object Boolean]’类型转成’boolean’类型并返回。若class2type存储的没有这个变量的类型,那就返回”object”。

除了”object”和”function”类型,其他的类型则使用typeof进行检测。即 number, string, boolean类型的变量,使用typeof即可。

本文讲解了【js基础】变量类型判断 更多相关内容请关注php中文网。

相关推荐:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML阻止iframe跳转页面并使用iframe在页面内嵌微信网页版

昨天看到这篇文章[置顶]开源组件NanUI一周年 - 使用HTML/CSS/JS来构建.Net Winform应用程序界面 就想弄一个winform结合html5的一个小东西&#xff0c;突有兴致&#xff0c;想在里面嵌套一个微信网页版。 好了&#xff0c;想法一出来&#xff0c;就行动吧&#xff0c;最终效果…

使用Spring Data Redis进行缓存

在下面的示例中&#xff0c;我将向您展示如何使用Spring Data – Redis项目作为Spring 3.1中引入的Spring Cache Abstraction的缓存提供程序。 我对如何使用Spring的基于Java的配置有很多疑问&#xff0c;因此我将同时提供基于XML和Java的配置供您查看。 依存关系 在此示例中使…

标准模板库(STL)学习指南之set集合

set是关联容器。其键值就是实值&#xff0c;实值就是键值&#xff0c;不可以有重复&#xff0c;所以我们不能通过set的迭代器来改变set的元素的值&#xff0c;set拥有和list相同的特性&#xff1a;当对他进行插入和删除操作的时候&#xff0c;操作之前的迭代器依然有效。当然删…

搜狗语料库数据整编

1 #!/bin/bash2 if [ -z "$1" ] ; then3 echo "请指定输入目录"4 exit 15 elif [ ! -d $1 ] ; then6 echo "[$1]不是一个合法的输入路径"7 exit 18 fi9 if [ -z "$2" ] ; then 10 echo "请指定输出目录" 11 exi…

linux oracle swd.oui,centos7安装oracle11g报错,请问怎么解?

centos7安装oracle11g报错&#xff0c;请问怎么解&#xff1f;在centos7下安装oracle11g到85%时报错提示Error in invoking target install of makefile ins_ctxm.mk查了log提示如下INFO: Start output from spawned process:INFO: ----------------------------------INFO:INF…

CSS布局技巧之——各种居中

居中是我们使用css来布局时常遇到的情况。使用css来进行居中时&#xff0c;有时一个属性就能搞定&#xff0c;有时则需要一定的技巧才能兼容到所有浏览器&#xff0c;本文就居中的一些常用方法做个简单的介绍。 注&#xff1a;本文所讲方法除了特别说明外&#xff0c;都是兼容…

OpenJPA:内存泄漏案例研究

本文将提供完整的根本原因分析详细信息以及解决影响Oracle Weblogic Server 10.0生产环境的Java堆内存泄漏&#xff08;Apache OpenJPA泄漏&#xff09;的方法。 这篇文章还将演示在管理javax.persistence.EntityManagerFactory生命周期时遵循Java Persistence API最佳实践的重…

了解真实的rem手机屏幕适配

rem 作为一个低调的长度单位&#xff0c;由于手机端网页的兴起&#xff0c;在屏幕适配中得到重用。使用 rem 前端开发者可以很方便的在各种屏幕尺寸下&#xff0c;通过等比缩放的方式达到设计图要求的效果。 rem 的官方定义『The font size of the root element.』&#xff0c;…

JDBC查询Oracle全部表名称,如何使用JDBC API从Oracle数据库中的现有表中检索记录?...

您可以使用UPDATE查询来更新/修改表中记录的现有内容。使用此功能&#xff0c;您可以更新表的所有记录或特定记录。语法UPDATE table_nameSET column1 value1, column2 value2...., columnN valueNWHERE [condition];要使用JDBC API更新表中记录的内容&#xff0c;您需要-注…

JUnit与EasyMock合作

开发人员始终需要注意所产生的代码。 在实施新功能或修复某些错误之后&#xff0c;应确保它们能够正常工作。 至少可以借助单元测试来实现。 由于此博客致力于Java编程语言&#xff0c;因此今天我将撰写有关JUnit 4.1和EasyMock 3. 1框架的文章。 这些框架的主要目的是简化单元…

nodejs获取当前url和url参数值

//需要使用的模块 http url 当前url http://localhost:8888/select?aa001&bb002 var http require(http); var URL require(url); http.createServer(function(req, res){var arg url.parse(req.url).query; //方法一arg > aa001&bb002var arg url.parse(…

以A表中的值快速更新B表中记录的方法

1、问题描述 有两张表&#xff0c;A表记录了某些实体的新属性&#xff0c;B表记录了每个实体的旧属性&#xff0c;现在打算用A中的属性值去更新B中相同实体的旧属性&#xff0c;如下图所示&#xff1a; 类似这样的需求&#xff0c;怎样做比较高效呢&#xff1f; 2、制作模拟数…

linux日志文件备份,LINUX 自动备份程序日志(shell)

定期备份脚本案列用tar压缩7天前日志删除7天压缩完日志删除压缩完356天前日志#&#xff01;/bin/bash#delete expire log#script name drop_log#script default remove 7 day log and remove remove archived a year ago#make date 2015/06/15result_clientfind /orafile/app/s…

HTML 网页创建

最简单的方式就是创建一个文本文档&#xff0c;然后将.txt后缀改为.html或者htm。 完成上面的步骤会创建一个完全空白的网页&#xff0c;下面填充一点内容&#xff0c;代码实例如下: <!DOCTYPE html> <html> <head> <meta charset" utf-8">…

Hadoop赠品–综述

各位极客&#xff0c; Packt Publishing关于Apache Hadoop 的书籍赠品已经结束。 您可以在此处找到比赛的原始帖子。 获奖者 将会获得这本书奖的6位幸运获奖者是&#xff08;姓名出现在他们的电子邮件中&#xff09;&#xff1a; Hadoop真实世界解决方案手册 Sellamuthu&…

企业级应用与互联网应用的区别

企业级应用&#xff1a;商业组织、大型企业而创建并部署的解决方案及应用。涉及的外部资源众多、事务密集、数据量大、用户众多、同时必须有较强的安全性考虑。 企业应用和互联网应用从根本来说是相同的&#xff0c;都是基于因特网、HTTP、浏览器的一种应用&#xff0c;但面向的…

hdu-2602 Bone Collector

题目 http://acm.hdu.edu.cn/showproblem.php?pid2602 分析 基础背包问题,有一个容量为V的背包,各种骨头有大小和价值两种属性,求背包能装的骨头的最大价值. AC代码 #include "bits/stdc.h" using namespace std; int val[1010], vol[1010], dp[1010]; int main(int…

linux vfs open函数,Linux VFS中open系统调用实现原理

用户空间的函数在内核里面的入口函数是sys_open通过grep open /usr/include/asm/unistd_64.h查找到的#define __NR_open2__SYSCALL(__NR_open, sys_open)观察unistd_64.h&#xff0c;我们可以猜测用户空间open函数最终调用的系统调用号是2来发起的sys_open系统调用(毕竟glibc一…

从如何停掉 Promise 链说起

在使用Promise处理一些复杂逻辑的过程中&#xff0c;我们有时候会想要在发生某种错误后就停止执行Promise链后面所有的代码。 然而Promise本身并没有提供这样的功能&#xff0c;一个操作&#xff0c;要么成功&#xff0c;要么失败&#xff0c;要么跳转到then里&#xff0c;要么…

JAXB教程–入门

注意&#xff1a;请查看我们的Java XML绑定JAXB教程– ULTIMATE指南 什么是JAXB&#xff1f; JAXB代表用于XML绑定的Java体系结构。它用于将XML转换为java对象&#xff0c;并将java对象转换为XML。JAXB定义了一个用于在XML文档中读写Java对象的API。与SAX和DOM不同&#xff0c…