0

0

【js基础】变量类型判断

jacklove

jacklove

发布时间:2018-06-11 22:36:25

|

2325人浏览过

|

来源于php中文网

原创

类型判断方法比较:

这里写图片描述

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

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

在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。

  1. 使用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。

  1. 使用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;切记,不然很难跟踪问题!

  1. 使用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是不是数组。

Tome
Tome

先进的AI智能PPT制作工具

下载

我们现在再来看看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]],然后把类型检测转化为字符串比较,以达到我们的目的。

  1. 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中文网。

相关推荐:

JQuery中DOM操作——wrap

django 使用 request 获取浏览器发送的参数

React this绑定的几点思考

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

246

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

34

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 7.1万人学习

Vue 教程
Vue 教程

共42课时 | 9.5万人学习

React 教程
React 教程

共58课时 | 6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号