JavaScript 数据类型详解
发布时间 - 2026-01-11 00:08:47 点击率:次一,数据类型

以下内容基于ES5(ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型。)
JavaScript是一种弱类型动态语言,定义变量时无需指定类型,看似简单,但背后有繁琐的转换逻辑。让我们一起来看下js常见的数据类型和背后的隐式转换逻辑。
ES5中有5种简单的数据类型(也叫基本数据类型):number,string,boolean,null,undefined(null和undefined是两种特殊的基本数据类型,下面会讲到);还有一种复杂数据类型——Object(函数是一种特殊的对象,后面会讲到)
Undefined类型:
Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined,例如:
var message; alert(message == undefined);//true
这个例子只声明了变量message,但未对其进行初始化。比较这个变量与undefined字面量,结果表明它们是相等的。这个例子与下面的例子是等价的:
var message = undefined; alert(message == undefined);//true
这个例子是用undefined值显示初始化了变量message.但我们没有必要这么做,因为未经初始化的值默认都会取得undefined值。
(一般而言,不存在需要显示地把一个变量设置为undefined值的情况。字面值undefined的主要目的是用于比较,而ECMA-262第3版之前的版本中并没有规定这个值。第3版引入这个值是为了正式区分空对象指针与未经初始化的变量。)
不过,包含undefined值的变量与尚未定义的变量还是不一样的。请看下面的例子:
var message;//这个变量声明之后默认取得了undefined值 //下面这个变量并没有声明 //var age alert(message);//'undefined' alert(age);//产生错误 Uncaught ReferenceError: age is not defined(…)
运行以上代码,第一个警告框会显示变量message的值,即'undefined'。而第二个警告框由于传递给alert()函数的是尚未声明的变量age,则会导致一个错误。对于尚未声明过的变量,只能执行一项操作,即使用typeof操作符检测其数据类型。
然而,令人困惑的是:对未初始化的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined值。来看下面的例子:
var message;//这个变量声明之后默认取得了undefined值 //下面这个变量并没有声明 //var age alert(typeof message);//'undefined' alert(typeof age);//'undefined'
结果表明,对未初始化和未声明的变量执行typeof操作符都返回了undefined值,这个结果有其逻辑上的合理性,因为虽然这两种变量从技术角度看有本质区别,但实际上无论对哪种变量也不可能执行真正的操作。
(即使未初始化的变量会自动被赋予undefined值,但我们仍然建议读者养成显式初始化变量-即在声明变量的同时给变量赋值的习惯。如果能够做到这一点,那么当typeof操作符返回undefined值时,我们就知道被检测的变量是还没有被声明的,而不是尚未初始化的了。)
Null类型
Null类型是第二个只有一个值的数据类型,这个特殊的值就是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是typeof操作符检测null值会返回'Object'的原因,如下面的例子所示:
var car = null; alert(typeof car);//'object'
如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值。这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用了,如下面的例子所示:
if(car != null){
//对car执行某些操作
}
实际上,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true;
alert(null == undefined);//'true'
这里,位于null和undefined之间的相等操作符(==)总是返回true,不过要注意的是,这个操作符出于比较的目的会转换其操作数(后面会详细介绍相关内容)。
尽管null和udefined有这样的关系,但它们的用途完全不同。如前所述,无论在什么情况下,都没有必要把一个变量的值显式地设置为undefined,可是同样的规则对null却不适用。换句话说,只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存null值。这样做不仅可以体现null作为空对象指针的惯例,而且也有助于进一步区分null和undefined。
二,隐式转换
+和-
在js中,虽然我们不需要显式地定义变量的类型,但在实际的处理中,会根据不同的类型,会有不同的处理。先看几个例子:
var x = 'The answer is ' + 42;//"The answer is 42" 这里的'+'会理解为字符串拼接 var y = 42 + ' is the answer';//"42 is the answer" 这里的'+'会理解为字符串拼接 '37' + 7;//"377" 这里的'+'会理解为字符串拼接 '37' - 7;//30 这里的'-'会理解为减法运算
我们也可以巧用类型转换,去做一些事情,比如想把一个变量num转换为数字类型,非常简单的办法就是减去数字‘0',如果想把一个变量num变为字符串类型,那么可以加上一个空字符串''。
var num; num = num - 0; alert(typeof num);//"number" num = num + ''; alert(typeof num);//"string"
===
严格等于a===b,首先会判断等号两边的类型,如果两边的类型不同,直接返回false,不再往下进行,如果类型相同,判断值是否想等。需注意NaN和任何东西比较都不想等,包括和自己比较也不想等。另外,JavaScript中的对象的比较是用引用去比较,而不是用值去比较,所以比较两个对象也不相等,因为不是两个完全相同的对象。可以定义变量x(不区分类型),让x和x比较,返回true。
'1.23' === '1.23';//true null === null;//true undefined == undefined;//true null === undefined;//false NaN === NaN;//false NaN属于number值,和任何东西比较都不想等,包括和自己比较也不想等 NaN == NaN;//false NaN属于number值,和任何东西比较都不想等,包括和自己比较也不想等 [1,2] == [1,2];//false 由于js中对象的比较是用引用去比较,虽然两边都是数组,而且长度一样、相同的值、相同的顺序,也是不等的,因为不是完全相同的对象。 new Object() == new Object();//false 引用比较,两个空对象是不同的两个对象,不相等。 var x; x === x;//true 定义变量x,,让x和x比较 返回true
==
如果类型相同,比较方法同'===',如果类型不同,会尝试类型转换和比较:
null == undefined //相等
number == string //尝试把string转换成number再去比较
1.0 == '1.0';//true
boolean == ? //无论右边是什么,会先把boolean先转换成数字,true转换成1,false转换成0,然后再去和右边的比较
true == 1; //true.
object == number | string //会尝试把对象转换为基本类型再去比较 其他的情况是false.
new String('hi') == 'hi';//true
new Boolean(false) == 0;//true
三,包装对象
number,string,boolean这三种基本类型都有对应的包装类型,先看一个例子:
从上面的例子可以看出,js中当把一个基本类型(比如string类型)尝试以对象的方式去使用的时候,比如访问它的length属性,或者增加一些属性的时候,js会很智能地把被操作的基本类型转换成对应的包装类型对象,(相当于new String()),这个临时包装对象的内容和基本类型的值是一样的,当完成访问或者属性设置的时候,这个临时包装对象会被销毁掉,所以再去访问已经设置的属性,是访问不到的。number和boolean基本类型转换成包装类型对象的原理都是一样的。
var a = 'string';//定义变量a,赋值基本类型'string' alert(a.length);//"6" 创建对应的临时包装对象,访问临时包装对象的length属性,得到结果6 a.t = 3;//3,设置成功后,临时对象被销毁,所以下面alert值是undefined alert(a.t);//"undefined"
var b = 123; b.toString();//"123" 调用对应临时包装对象Number()上的toString()方法,转换成字符串
四,类型检测
1,最常见的是用typeof操作符,会返回一个字符串,适合函数对象和基本类型的判断,遇到null失效,会返回Object。
typeof 100 //"number" 数值 typeof NaN; //"number" 数值 typeof Infinity;//"number" 数值 typeof true //"Boolean" 布尔值 typeof(undefined); //"undefined" 表示这个值未定义 typeof new Object(); //"object" 对象 typeof [1, 2]; //"object" 数组是对象,没有特殊处理 typeof null; //"object" null值表示一个空对象指针,所以返回Object typeof function //"function" 从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型,然而,函数也确实有一些特殊的属性,因此通过typeof操作符来区分函数和其他对象是有必要的
2,如果要判断对象类型,常用的是instanceof,适合自定义对象,也可以用来检测原生对象,在不同iframe和window间检测时失效,是基于原型链去判断,instanceof原理: 判断obj对象的原型链上是否有右边的构造函数的prototype属性,关于原型链,详见后面篇章。
obj instanceof Object(obj:必须是对象,如果是基本类型,直接会返回false; Object:必须是函数对象,或者函数构造器,如果不是,就会抛出TypeError异常。)
看下简单的例子
new Object() instanceof Array === false //true [1, 2] instanceof Array === true //true [] instanceof Array===true//true
我们知道,任何一个构造函数,都有一个prototype对象属性,这个对象属性将用作使用new构造函数这种方式构造出的对象的原型。比如Person这个函数,函数有prototype属性. 我们用new Person()去创建Person实例的时候,这个对象实例就会有一个原型指向Person.prototype这个对象。我们用var bosn=new Student(),创建一个Student实例bosn,bosn的原型会指向它的构造器Student的prototype对象属性。检测bosn instanceof Person时,bosn.__proto__=Student.prototype,然后原型链会继续往上查找,bosn.__proto__.__proto__=person.prototype.就会返回true。注意,不同window或iframe间的对象类型检测不能使用instanceof!
3,Object.prototype.toString()判断类型,适合内置对象和基本类型,遇到null和undefined失效,IE6/IE7/IE8返回'[object Object]'
Object.prototype.toString.apply([]);==='[object Array]';
Object.prototype.toString.apply(function(){});==='[object Function]';
Object.prototype.toString.apply(null);==='[object Null]';//IE6/IE7/IE8返回'[object Object]'
Object.prototype.toString.apply(undefined);==='[object Undefined]';//IE6/IE7/IE8返回'[object Object]'
Object.prototype.toString.apply('123');==="[object String]";
Object.prototype.toString.apply(123);==="[object Number]";
Object.prototype.toString.apply(true);==="[object Boolean]";
Object.prototype.toString.apply(String);==="[object Function]";
Object.prototype.toString.apply(Boolean);==="[object Function]"
4,constructor检测类型
任何一个对象都有一个constructor属性,继承自原型,会执向构造这个对象的构造函数, constructor可以被改写,使用时要小心。
5,duck type检测类型
比如我们不知道一个对象是否是数组,我们可以判断这个对象的length是否是数字,是否有join,push等数组的函数方法,通过特征判断对象是否属于某些类型,有时也会用到。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
# js
# 数据类型
# 老生常谈js数据类型
# javascript基本数据类型和转换
# 详解js的六大数据类型
# 浅谈javascript中的数据类型转换
# 详解Javascript数据类型的转换规则
# JS中检测数据类型的几种方式及优缺点小结
# 简单谈谈js的数据类型
# 的是
# 转换成
# 就会
# 再去
# 都有
# 还没有
# 是一种
# 也会
# 而不是
# 对其
# 第二个
# 只有一个
# 任何一个
# 所示
# 想把
# 设置为
# 转换为
# 讲到
# 先看
# 完全相同
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
,在苏州找工作,上哪个网站比较好?
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
网站制作大概多少钱一个,做一个平台网站大概多少钱?
google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤
如何快速生成ASP一键建站模板并优化安全性?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
JavaScript如何实现继承_有哪些常用方法
JS经典正则表达式笔试题汇总
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
深圳网站制作的公司有哪些,dido官方网站?
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
Laravel如何使用Blade模板引擎?(完整语法和示例)
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
Laravel如何实现用户注册和登录?(Auth脚手架指南)
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
音乐网站服务器如何优化API响应速度?
Laravel如何实现本地化和多语言支持?(i18n教程)
Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
JavaScript常见的五种数组去重的方式
南京网站制作费用,南京远驱官方网站?
Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】
如何做网站制作流程,*游戏网站怎么搭建?
利用 Google AI 进行 YouTube 视频 SEO 描述优化
C语言设计一个闪闪的圣诞树
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
Python制作简易注册登录系统
nodejs redis 发布订阅机制封装实现方法及实例代码
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
创业网站制作流程,创业网站可靠吗?
javascript如何操作浏览器历史记录_怎样实现无刷新导航
文字头像制作网站推荐软件,醒图能自动配文字吗?
Laravel中的withCount方法怎么高效统计关联模型数量
Laravel如何使用.env文件管理环境变量?(最佳实践)
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】
Laravel怎么实现模型属性的自动加密
Laravel如何使用withoutEvents方法临时禁用模型事件
专业商城网站制作公司有哪些,pi商城官网是哪个?
,南京靠谱的征婚网站?
Laravel如何集成Inertia.js与Vue/React?(安装配置)

