JavaScript的数据类型

js数据类型.png

JavaScript中总共有6种数据类型。可分为两大类:简单数据类型复杂数据类型

说明一下:上面这句话现在来说应该是不对的,因为ES6中新增了数据类型。不过我们暂时不涉及ES6。

简单数据类型即基本数据类型,共有5种:UndefinedNullBooleanNumberString,其值分别对应undefinednull、布尔值truefalse数值字符串值。

复杂数据类型只有一种,就是Object——对象。JS中的对象就是一组无序键值对外面套一个大括号{}所构成。Object非常常用、非常强大、非常有意思,而且对于JS这门语言结构来说,Object意义不一般。这些,之后的文章再来讨论吧。

ECMAScript不支持任何创建自定义类型的机制,而所有值最终都将是上述6种数据类型之一。

上面这句话引用自《JavaScript高级程序设计(第3版)》(之后简称J3),其实不用多解释,这句话说的很明白了。这就是说,你“定义”的所有变量,它的类型都是唯一确定的,必定是上述6种之一。

这里的“定义”两个字,我加了引号,是想表示这个词广义上的意思。在一般的编程语言中,当你想“定义”一个变量时,不外乎3种情况:声明,定义,初始化。声明就如字面意思一样,仅仅是宣称一个命名;定义就是给这个命名分配内存空间;初始化则是给这个内存空间赋值。显然,他们3个是循序渐进的。在JS中,我们所说的初始化其实做的事是分配内存并赋值,也就是定义并初始化。所以在JS中,我们一般只说声明和初始化。看如下代码:

var value1;  //声明变量
value1 = 'Hello';  //(定义并)初始化
var value2 = 'Hello';    //声明并初始化

再摘录博客园的一句话,对于声明、定义与初始化大家应该就能完全理解了:

因为javascript为动态语言,其变量并没有固定的类型,其存储空间大小会随初始化与赋值而变化,所以其变量的“定义”就不像传统的静态语言一样了,其定义显得无关紧要。
http://www.cnblogs.com/silentjesse/p/4024536.html


接下来,让我们来具体看一看JavaScript的6种数据类型。

不过首先,必须先了解一个操作符—typeof。顾名思义,这个操作符的作用就是返回某个变量的数据类型。对某个值使用typeof操作符始终会返回以下6个字符串之一:'undefined''boolean''number''string''object''function'。你肯定发现了一个问题,就是这6个字符串为什么不和6种数据类型完全对应?没有'null'吗?'function'又是哪儿来的?请看下面的测试代码:

console.log(typeof null)    //'object'
var f = function(){};
console.log(typeof f);    //'function'

注意到,对Null类型的唯一值null使用typeof操作符返回的不是什么'null',而是'object',这是为什么呢?这是因为null这个值比较特殊,它是基本数据类型Null的唯一值,但同时,它又被认为是一个空的对象(Object)引用。

有些时候,typeof 操作符会返回一些令人迷惑但技术上却正确的值。比如,调用typeof null会返回"object",因为特殊值null 被认为是一个空的对象引用。——《J3》

对于typeof可以返回'function',这么理解吧:

从技术角度讲,函数在ECMAScript 中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof 操作符来区分函数和其他对象是有必要的。——《J3》

在JS中,FunctionObject的关系很微妙也很复杂,需要对原型构造、原型链等一些知识有所理解之后才能进一步理解这两者的关系。不过这并不影响我们现在的理解,站在数据类型的角度,我们可以明确地认为Function就是一类特殊的Object。至于对一个Function使用typeof操作符的返回结果是'function'而不是'object',原因就像书上说的,只是因为我们有必要知道它是一个函数而不是一般的对象。


介绍完typeof操作符这个实用的工具,下面就真的具体来看看JS的6种数据类型吧。

Undefined 类型

  • 只有一个唯一值,即undefined
  • 所有只进行了声明而未初始化的变量,其值都是undefined。比如:
var a;
console.log(a);    //undefined(注意,这可不是字符串)

需要明白的是,undefined是一个明确的、合法的值,而不是一个错误。真正会导致错误的是如下的代码:

console.log(b);    //Uncaught ReferenceError: b is not defined

这行代码会报一个空引用异常的错误,因为变量b没有声明。这很好理解。

  • 还有一点需要了解,对于上边两段示例代码中的变量 a 和 b,执行typeof操作都会返回'undefined'
var a;
console.log(typeof a);    //'undefined'
console.log(typeof b);    //'undefined'

看起来,你可能会觉得对 b 执行typeof应该报错才对,但因为typeof必然会返回6个字符串之一,所以并不会报错。而且,无论是 a 还是 b,都无法执行真正的操作,那么就让 b 和 a 一样返回'undefined'好了。看一下书上的解释:

结果表明,对未初始化和未声明的变量执行typeof 操作符都返回了undefined 值;这个结果有其逻辑上的合理性。因为虽然这两种变量从技术角度看有本质区别,但实际上无论对哪种变量也不可能执行真正的操作。——《J3》

由此可知,当你使用typeof操作符检测变量的数据类型时,如果返回的是'undefined',那么这个变量可能是未初始化,也可能是未声明。因此,从规范性上来说,为了避免这种模糊,我们在定义变量时最好直接进行初始化。这样的话,如果还返回'undefined',那么我们立即就能知道是因为这个变量压根就没声明了。

Null 类型

  • 只有一个唯一值,即null
  • null表示一个空对象(Object)引用,因此typeof null会返回'object'
  • 实际上,undefined派生自null,因此undefined == null返回true,但是undefined === null会返回false,因为这两个值的数据类型不一样。这里补充一下:==是相等操作符,===是全等操作符,前者会对操作数自动进行转型,而后者不会,后者只有在两个操作数未经转换就相等的情况下才返回true
  • 还有一点,如果某个变量用来在以后保存对象,那么最好将其初始化为null,以方便区分和判断。

Boolean 类型

  • 布尔类型,有2个值:truefalse
  • 其他所有数据类型都有与truefalse对应的值,通过转型函数Boolean()可以得到某个值所对应的布尔值。如:
var s = 'Hello';
console.log(Boolean(s));    //true

转换规则如下表:

Boolean()转型函数的转换规则

在流程控制语句中,比如在if语句的小括号内,会自动对操作数调用转型函数Boolean()再求最终的布尔值。如下:

var s = 'Hello';
if(s){
    //do something    //后台自动对s调用转型函数`Boolean()`,因为s不是空串,会返回true
}

Number 类型
数值类型。了解几个知识点即可。

  • 保存浮点数所需的内存空间是整数值的2倍;
  • 永远不要测试特定的浮点数值,如:
var a = 0.1;
var b = 0.2;
console.log(a + b);    //0.30000000000000004 有误差,并不会是0.3
  • NaN是一个特殊的Number值,它的存在是为了避免程序直接报错,比如0/0的结果就是NaNNaN的任何操作都会返回NaNNaN与任何值都不相等,包括它本身:NaN === NaN会返回false
  • 另外,还有parseInt()parseFloat()等常用转型函数的用法自行Google即可。

String 类型
字符串类型。在这里了解几个点即可,之后在引用类型等处会做详细介绍。

  • 单引号''和双引号""都可以使用且没有任何差别。

  • ECMAScript 中的字符串是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。——《J3》

  • 将某个值转换为字符串,可以使用以下3种方法:toString()方法、转型函数String()、加空串+ ''

Object 类型
对象类型。Object是所有对象的基础,其所具有的属性和方法其他对象也必然拥有。这里只列几个Object的属性和方法:

  • constructor:保存着用于创建当前对象的构造函数;
  • hasOwnProperty('属性名'):用于检查给定的属性在当前对象实例中是否存在(不查找原型链);
  • isPrototypeOf(某一Object类型):用于检查对象实例是否是传入对象的原型;
  • propertyIsEnumerable('属性名'):用于检查传入的属性是否可以枚举;
  • toString():返回该对象的字符串表示;
  • toLocalString():同上,与所在地区有关
  • valueOf():返回对象最有意义的那个值,返回的可能是字符串、数值或者布尔值。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容