JavaScript 数据类型
编程语言中,能够表示并操作的值的类型称为数据类型,编程语言最基本的特性就是能够支持多种数据类型。
[ 编程领域中的数据类型 ] 在编程领域中,数据类型(datatype)用来将变量的值(value)进行分类,这样对变量的值进行数字、关系、逻辑等运算时就不会产生错误了。
2*2 // 符合逻辑 2 * 'tom' // 不太符合逻辑
JavaScript 数据类型
ECMAScript 中有 5 种简单数据类型(又称为基本数据类型:Number、String、Boolean、Undefined、Null)和 1 种复杂数据类型 — Object。Object,本质上是由一组无序的名值对组成的。
ECMAScript 不支持任何创建自定义类型的机制,所有值始终都将是上述 6 种数据类型之一。实际上,由于 ECMAScript 数据类型具有动态性,因此,的确没有再定义其他数据类型的必要了。
简单来说,JavaScript 的数据类型分为两类:原始类型和对象类型(Object)。
- 原始类型主要包括:Number、String、Boolean、
Symbol(ES6新增)和空值(Null、Undefined)。- JS 中除原始类型之外的都是对象 Object,对象是键值对的集合,值可以是原始值,也可以是对象。
与此相对应,原始类型和对象类型的值,也分别被称为原始值和复杂值。
- 特性:原始值,不可更改;复杂值,是可变的,它们的值可以修改;
- 存储方式:原始值,栈存储;复杂值,堆存储;
- 访问方式:原始值,值访问;复杂值,引用访问;
- 比较方式:原始值,值比较,复杂值,引用比较。复杂值只在引用相同的对象(即有相同的地址)时才相等。
- 动态属性:复杂值,可以添加、改变和删除其属性和方法;但原始值不可添加属性和方法。
[1] 空值
- Undefined 类型
Undefined 类型只有一个值:即特殊的 undefined,表示未定义或不存在。
# 在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined。 var abc; // 这个变量未初始化 console.log(abc); // undefined # 其他场景:已声明未赋值的变量 / 获取对象不存在的属性 / 无返回值的函数执行结果 / 函数参数没有传入 / void(expression) var obj = {}; console.log(obj.name); // undefined # 对于尚未声明过的变量只能执行一项操作,使用typeof操作符检测其数据类型,严格模式下会出错。 // var abcd; // 这个变量并没有声明 console.log(abcd); // 报错,注意未声明和未赋值的区别 # 令人困惑的是,对未初始化的变量和未声明的变量执行 typeof 操作符都会返回 undefined 值,但实际意义不大。 typeof abc; // undefined typeof abcd; // undefined console.log(abc == abcd); // true
- Null 类型 // 变量的值如果想为 null,必须手动设置
Null 类型是第二个只有一个值的数据类型,即 null。从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回“Object”的原因。
# 实际上,undefined 的值是派生自 null 值的,因此,ECMA-262 规定对它们的相等性测试要返回 true。
console.log(null == undefined);尽管 null 和 undefined 有这样的关系,但它们的用途完全不同。无论什么情况下,都没有必要把一个变量的值显式的设置为 undefined,可同样的规则对于 null 却不适用。换句话来说,如果定义的变量准备在将来用于保存对象(还没有真正保存对象),就应该明确的让该变量保存为 null 值。
这样做,不仅可以体现 null 作为空对象指针的惯例,而且有助于进一步区分 null 和 undefined。
# 判断一个值是否为null类型的最佳方法是直接和 null 进行恒等比较。
console.log(document.getElementById('test')); // null // null是空对象指针,而[]是空数组,{}是空对象,三者不相同。 console.log(typeof null); // 'object
[2] Boolean 类型 ?↓
布尔是计算机科学中的逻辑数据类型,以发明布尔代数的数学家乔治 · 布尔为名,用来表示真或假、开或关等含义。
Boolean 类型是 ECMAScript 中使用最多的一种类型,该类型只有两个字面值:true 和 false,且区分大小写 。
// 在计算机内部存储,true 为 1,false 为 0
var yes = true;
var no = false;
// 布尔值与控制语句
布尔值通常用于 if/else 控制语句,如果为 true,则执行 if 里面的逻辑,否则执行 else 里面的逻辑。
if(status=='open'){
console.log('The door is open');
}else{
console.log('The dooor is closed');
}
// 布尔值:假值和真值
任意值都可以转换为布尔值。一共有 6 个值(假值)会转换为 false,其他值(真值)都是 true。
// 6 个假值:undefined null 0 -0 NaN ""
[3] Number 类型 ?↓( 对象 )
JavaScript 不区分整数和浮点数,所有的数值都用浮点数表示,采用 IEEE 754 标准定义的 64 位浮点格式。
[ 数值直接量和负值 ] JS 中的数值,称为数值直接量;在它前面添加负号(-,一元求反运算符),可以得到它的负值。
var num1 = 1; var num2 = -2;
[ 进制表示 ] 进行算数运算时,二进制、八进制和十六进制表示的数值最终都将被转换成十进制数值。
- 整数:范围是-2∧53~2∧53,可以用十进制、二进制、八进制、十六进制表示。
- 0b11:二进制(binary)以 0b为前缀,之后的值由 0~1组成;
- 067:八进制(octal)以 0 为前缀,之后的值由 0~7组成;
- 0xAf:十六进制(hexadecimal)以 0x为前缀,之后的值由 0~9和 a~f(10~15)组成;
所有二进制、八进制、十六进制中的字母不区分大小写,包括前缀中的字母;以 0 为前缀的八进制,不推荐使用,在严格模式下会报语法错误。
- 浮点数:数值中必须包含一个小数点,小数点后至少要有一位数字。如 3.14 .14
对于极大或极小的浮点数,可以使用科学计数法。如 3.14e10,即 3.14*(10∧10)
浮点数计算可能会有误差(使用 IEEE754 标准的浮点数计算的通病),如 0.1 + 0.2 = 0.30000000000000004
- 特殊值:JS中,还有一些特殊值,主要来自:全局直接量、Number对象的属性、Math对象的属性等。
Infinity NaN Number.MAX_VALUE Number.MIN_VALUE Math.PI
[4] 字符串类型 String?↓
字符串用来表示文本,由零个或多个16位Unicode字符组成的字符序列;可以使用单引号(推荐)或双引号,但必须成对出现;索引从零开始,第一个是 0,第二个是 1,以此类推;长度是字符的个数。
'abc' "123" // ‘ab"c’ // 有效(双引号作为字符串内容) “ab'c” // 有效 “abc’ // 无效 // 推荐写法:单引号 JS代码中,经常会出现HTML字符串。由于HTML标签中的属性值推荐的是双引号,所以,JS中字符串推荐使用单引号。 var imgEl = '<img src = "logo.jpg" title="logo">';
[ 转义字符 ] 反斜杠后加一个字符表示转义字符,如 \n 表示换行符。
‘abc\'d’ 'abc\nd' // 常见的转义字符(如果斜杠后面的字符没有特殊含义,则忽略斜杠。如,\a等同于a。) \n 换行 \\ 斜杠 \' 单引号,在用单引号表示的字符串中使用 \" 双引号,在用双引号表示的字符串中使用 \xnn 十六进制代码表示的一个字符(其中n为0~F)。如,\x41表示“A”。 \unnnn 十六进制代码表示的unicode字符(其中n为0~F)。如\u03a3表示希腊字符∑。[ 模板字符串 ] ES6 新增的写法,是允许嵌入表达式的字符串字面量。
// 模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。 // 它可以包含特定语法 ${expression} 的占位符。 var abc = `abc`; alert(abc); // abc alert(`${abc}def`);
[5] Symbol
ES6 新增的原始类型,可用作对象的非字符串属性,它是唯一且不可变的。
let uniqueName = Symbol();
let person= {};
person[uniqueName] = 'tom';
console.log(person[uniqueName]); // =>John
[6] 对象 Object
ECMAScript 中的对象其实就是一组数据和功能的集合。
简单来说,除了原始类型的值外,其他的都是对象类型;对象是键值对的集合,值可以是原始值,也可以是对象。
var person = {
name:'tom',
age:25
}
// 重要的特殊对象:函数Function 数组Array 日期Date 正则RegExp 错误Error 全局Global
[ 数据类型的识别与转换 ?↓ ] 鉴于 ECMAScript 是松散类型的,因此,需要有一种手段来检测给定变量的数据类型 — typeof 就是负责提供这方面信息的操作符。需要说明的是,typeof 的结果是一个小写的字符串。
typeof 是一个操作符而不是函数,因此其后面的(),尽管可以使用,但不是必需的。
typeof 操作符的操作数可以是变量(message),也可以是数值字面量。
var abc; // undefined var abc = true; // boolean var abc = 123; // number var abc = 'abc'; // string var abc = function (){}; // function var abc = {}; // [],null // object var abc = Symbol(); // symbol alert(typeof abc); // alert(typeof(abc))