章节索引 :

JavaScript 数据类型

数据类型就是 JavaScript 中可操作的数据的类型。

数据类型分为值类型引用类型

在 ES6 之前,主要有以下数据类型:

  • 值类型
    • 字符串
    • 数字
    • 布尔
    • null
    • undefined
  • 引用类型
    • 对象
    • 数组
    • 函数

1. 为什么需要不同的数据类型

在学习自然数学的时候,所有的加法减法等操作都是针对数字的,数字加上操作符让他们有了意义。

在学习语文课的时候,不同的词语可以组合成句子,主谓宾语法与词语相互结合赋予了句子意义。

在 JavaScript 中也是如此,配合数据类型才能知道怎么对数据进行操作。

上一小节有提到的字符串与数字就是如此。

3 + 4,JavaScript碰到两边都是数字,就会做对应的加法操作。

程序需要不同类型的数据表示不同的内容,分别做对应的处理。

2. 值类型

2.1 字符串

字符串由字符组成,字符串在使用的时候会使用双引号(")或者单引号(')包裹。

var str1 = '字符串';
var str2 = "字符串";

console.log(str1); // 输出:"字符串"
console.log(str2); // 输出:"字符串"

上述例子中,两个变量都是字符串类型的,可以双引号和单引号包裹的结果是一样的。

但是如果需要在双引号包裹的字符串中使用双引号,或者在单引号包裹的字符串中使用单引号,需要使用\进行转义,否则会报错,因为 JavaScript 无法知道字符串的结束位置。

var str1 = '使\'用\'单\'引\'号';
var str2 = "使\"用\"双\"引\"号";

console.log(str1); // 输出:"使'用'单'引'号"
console.log(str2); // 输出:"使"用"双"引"号"

// 以下代码会报错
var str3 = "哼"!";
var str4 = ''哼!';

大部分开发者会使用单引号包裹字符串。

因为为了网页的动态展示、复杂交互等,需要用 JavaScript 书写 HTML 模版,而 HTML 的属性按照习惯是使用双引号包裹的(XML 标准允许单引号和双引号,在 HTML5 的标准中甚至不需要书写引号)。

这样如果使用 JavaScript 中的字符串表示 HTML 就会变成如下情况:

var html = "<div class=\"title text-red\" style=\"display: inline-block;\">我是一个红色的标题</div>";

为了契合书写 HTML 的习惯,防止代码中充斥的大量的转义,就会使用如下使用单引号的形式。

var html = '<div class="title text-red" style="display: inline-block;">我是一个红色的标题</div>';

2.2 数字

数字是最好理解的一种类型,因为生活中都会接触到。

数字可以细分为浮点数和整数,浮点数就是带有小数位的数,但事实上在 JavaScript 只有64位的浮点数,具体的范围是 [-2^53 ~ 2^53],整数也使用浮点数表示。

数字类型也存在负数,如果数字的区间为 (0, 1),则可以省略小数点前的 0

var num1 = 5;
var num2 = .1;
var num3 = 0.5;
var num4 = -10;
var num5 = 884739573;

以上是数字的一些表示方式。

如果数字的大小超过最大值或者最小值,那他的值在 JavaScript 中会表示为 Infinity-Infinity

var base = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999;

var num1 = 99999 * base;

var num2 = -99999 * base;

console.log(num1); // 输出:Infinity
console.log(num2); // 输出:-Infinity

这两个值分别表示为无穷大无穷小

JavaScript 中还可以用数字表示二进制八进制十六进制

二进制是以 0b 开头的数字。

var val10 = 0b1010;
var val8 = 0b1000;

console.log(val10); // 输出:10
console.log(val8); // 输出:8

在输出的时候还是会以十进制的结果进行输出。

八进制则可以用 0 开头的数字表示。

var val56 = 070;

console.log(val56); // 输出:56

十六进制使用 0x 开头表示。

var val10 = 0xA;

console.log(val10); // 输出:10

十六进制是比较常用的一种方式,二进制和八进制的表示使用相对较少。

2.3 布尔

布尔值表示两种状态,如同使用零和一区分状态的开关一样。

图片描述

开关

布尔值两种状态对应 truefalse 两个值。

通常 true 被称为真值false 被称为假值,两者也被统一称为布尔值

var empty = true;

var isVIP = false;

通常在只有两种状态的情况下会使用布尔值。

以下值在转换成布尔值的时候会转换成 false

  • null
  • undefined
  • NaN
  • 0 ( 数字 0 )
  • 空字符串

2.4 null

null是一个非常特殊的类型,表示对象的值未设置,也可以简单理解成什么都没有

通常null会在应该获取到一个对象,但是没获取到的时候进行使用,结合对象会更好理解。

在初始化一个变量的时候,有时候类型不确定,或者应该是一个对象,但还有设置值的时候会使用到null。

var obj = null;

2.5 undefined

undefined从中文意思上理解就是不确定或者没有定义。

一个变量在声明后如果没有赋值,他的值就是undefined

var age;

console.log(age); // 输出:undefined

一个函数在没有指定返回值的时候,默认就会返回undefined

function fn() {
  console.log('我是名字为fn的函数');
}

var val = fn();

console.log(val); // 输出:undefined

函数fn没有提供返回值,但val的值为undefined

比较有趣的是,undefined既是一种数据类型,在浏览器中又是作为全局变量存在的,也就是window对象下的一个属性。

console.log('undefined' in window); // 输出:true

使用in关键字可以校验某个对象下是否存在某个属性。这里的意思就是undefined属性是否在window对象下存在。

控制台会输出布尔值true,为一个真值,表示属性是确实存在的。

3. 引用类型

3.1 函数

函数其实是一段 JavaScript 代码,调用函数就会执行函数中的代码。

使用 function 关键字就可以定义一个函数,简单的函数语法如下:

function 函数名(参数) {
  函数体;

  return 返回值;
}

var ret = 函数名(参数1) // 调用函数

函数名就是函数的名字,在调用函数的时候会被使用到。

参数则是传递给函数的数据,函数内部可以访问到传进来的参数。

return 则标志着函数的结束,返回值会被作为结果进行返回。

function add(arg1, arg2) {
  var sum = arg1 + arg2;

  return sum;
}

var num1 = add(1, 2);
var num2 = add(4, 2);

console.log(num1); // 输出:3
console.log(num2); // 输出:6

上面这个例子就是声明了一个名为 add 的函数,其功能就是把两个参数求和并返回。

可以看到函数让代码更加有 意义,调用 add 函数的地方可以很好的理解这里是在做求和操作,同时提高了代码的复用率。

3.2 对象

对象由属性和方法组成。

其格式如下:

var obj = {
  属性名1: 属性值1,
  属性名2: 属性值2,
  方法名1: 方法1,
  方法名2: 方法2,
  '属性名3': 属性值3,
};

属性名和方法名都为字符串,如果其符合变量命名规范,则可以不使用引号包裹。

本质上方法也可以算作一个属性,通常在对象里一个属性的属性值为一个函数,就会称之为方法。

var obj = {
  name: '小明',
  age: 12,
  say: function() {
    console.log('我叫' + this.name + ', 我的年龄是' + this.age + '岁');
  },
  'father-name': '小蓝',
};

console.log(obj.name); // 输出:小明
console.log(obj['father-name']); // 输出:小蓝

obj.say(); // 调用 say 方法,会输出:我叫小明, 我的年龄是12岁

上述例子中的 obj 对象具有三个属性(name、age、father-name)一个方法(say)。

属性可以是任意的数据类型,格式为属性名: 属性值,多个属性则由逗号(,)分隔,方法则只能为一个函数,通常会是一个匿名函数(函数相关的详细内容可以查阅函数章节)。

通过对象.属性就可以访问到对象属性的属性值,如果属性名是一个不符合变量命名规范的值,则可以通过对象['属性名']进行访问,方法同理,因为本质上方法也是属性。

既然属性可以是任意的数据类型,则也可以是一个对象:

var obj = {
  name: '小明',
  colors: {
    hair: 'red',
    eye: 'blue',
    skin: 'white',
  },
};

理论上在内存允许的情况下,可以进行无限层的对象嵌套。

以上的例子都是采用字面量的方式创建一个对象,还有许多种方式可以创建对象。

如使用Object构造一个新对象。

var obj = new Object();

obj.name = '小明';
obj.age = 16;

obj.colors = {
  hair: 'red',
  eye: 'blue',
};

console.log(obj.colors.hair); // 输出:red
console.log(obj.name); // 输出:小明

obj.name = '小红';

console.log(obj); // 将会在控制台输出 obj 对象

通过 new Object() 就可以创建一个新的对象。

通过对象.属性 = 属性值的方式就可以设置一个属性和属性值,这一方式遵循以下规则:

  • 如果要赋值的属性不存在,则会创建这个属性并赋值
  • 如果要赋值的属性存在,则会修改这个属性的值

另外还可以使用构造函数Object.create等方式创建对象,具体请参考对象章节。

3.3 数组

数组是一组数据构成的列表。

数组由中括号包裹,每一项通过逗号进行分隔:

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

console.log(arr[0]); // 输出:1
console.log(arr[1]); // 输出:"2"

和对象一样的是,数组的每一项也可以是任意类型的数据。

如果需要访问数组中的每一项可以通过数组[下标]的格式进行访问。

下标就是数组每一项的编号,这个编号从0开始,第一项为0,第二项为1,以此类推。

数组可以理解成一种特殊的对象,他原生具有一些方法,如遍历数组:

var arr = ['a', 'b', 'c'];

arr.forEach(function(item, index) {
  console.log(item, index); // "a" 0, "b" 1, "c" 2
});

通过数组.forEach的方式就可以遍历数组,forEach方法接受一个函数,这个函数在遍历到每一项的时候会被调用,并将每一项的值和下标作为参数传递过来。

既然具有一些方法,同样的也具有一些属性,最常用的就是length属性:

var arr = [1, 2, 3];

console.log(arr.length); // 输出:3

数组的 length 属性会返回数组的长度。

4. 值类型和引用类型的区分方式

从内存角度出发,值类型放在内存栈中,引用类型则放在内存堆中。

引用类型的数据长度是不固定的,如对象所占用的空间很大一部分由属性值决定,而属性值又可以是任意类型。

另外最大的区别就如分类名一样,引用类型的数据本身是指向内存上的一块地址,操作的时候对地址上的值进行操作。

而值类型直接操作值,不论是复制或是修改都是直接产生一个新的值。

var obj1 = {
  name: '小明',
};

var obj2 = obj1;

obj2.name = '小红';

console.log(obj1.name); // 输出:小红


var val1 = 1;
var val2 = val1;

val2 = 2;
console.log(val1); // 输出:1

通过上面的例子就可以看出引用类型和值类型在 JavaScript 程序中的区别。

引用类型在进行复制的时候,其实就是多了一个引用,操作的值是同一个。

而值类型进行复制后,则是一个新的值。

5. 小结

  1. 数据类型是比较重要的一个概念,在分类上分为引用类型和值类型。
  2. 值类型包括:字符串、数字、布尔、null、undefined。
  3. 引用类型包括:函数、对象、数组。
  4. 引用类型相对复杂,每一种类型也具有很多特性,其内容可以参阅对应的章节。
前置知识
什么是JavaScript 开发与学习环境准备 调试方案
基础
JavaScript 变量 JavaScript 数据类型 JavaScript if 语句 JavaScript for 语句 JavaScript 算数运算符 JavaScript 比较运算符 JavaScript 逻辑运算符 JavaScript 表达式 JavaScript 函数 JavaScript 对象 JavaScript 字符串 JavaScript 数字 JavaScript 数组 JavaScript switch 语句 JavaScript while 语句 JavaScript break与continue JavaScript with document.cookie
内置对象
JavaScript Function JavaScript Math JavaScript Date JavaScript RegExp JavaScript JSON
JavaScript 与 DOM
什么是DOM DOM和JavaScript的关系 获取和操作 DOM 节点 JavaScript DOM与事件 JavaScript DOM 事件绑定 JavaScript DOM 事件对象 JavaScript DOM 事件流 JavaScript DOM 事件优化 JavaScript DOM 自定义事件
表单处理
使用 JavaScript 校验表单
BOM
BOM window 对象 常用的 BOM 相关对象 BOM 常用属性和方法
AJAX
JavaScript AJAX
进阶知识
JavaScript 异常处理 JavaScript 三元运算符 JavaScript 逗号操作符 JavaScript void JavaScript typeof JavaScript delete JavaScript debugger JavaScript getter &setter JavaScript 原型 JavaScript new操作符和构造函数 JavaScript instanceof JavaScript this JavaScript 严格模式 JavaScript 作用域 JavaScript 闭包 JavaScript 变量提升 JavaScript 对象包装器
常用库
jQuery Lodash moment.js swiper
进阶指南
ECMAScript6 Node.js Babel CSS 预处理器 代码规范 TypeScript Web Components 小程序 Vue / React / Angular JavaScript 关键字
常见疑点与误区
分号问题 对象属性访问问题 this 使用问题 浮点数精度问题 独一无二的 NaN 避免全局污染 控制台观察对象问题 根据环境选择语言特性
扩展
相关资源