MDN-JavaScript数据类型
JavaScript中有6种简单数据类型(原始类型、原始值):Undefined、Null、Boolean、Number、String和Symbol,一中复杂数据类型Object
检测操作符typeof
JavaScript一种松散型的语言,变量只是存储值的占位符,其对应的值是可以随便改变的。所以需要一种手段来确定任意变量值的数据类型。typeof操作符返回的结果是字符串:
'undefined'表示值未定义(变量声明未赋值或未声明变量均返回undefined)"boolean"表示值为布尔值"string"表示值为字符串"number"表示值为数值"symbol"表示值为符号"function"表示值为函数"object"表示值为对象(不是函数)或null(空指针对象)
简单数据类型
Undefined类型
Undefined类型只有一个值,特殊值undefined。当使用var或let声明变量但是未初始化时则默认给变量赋予了undefined值
undefined是由null派生而来,在非严格模式下两者相等
let message;
// let age;
console.log(typeof message); // "undefined"
console.log(typeof age); // "undefined"
// 虽然未初始化和未定义变量使用`typeof`的返回值都是undefined,但是本质上还是有区别的
console.log(message); // undefined
console.log(age); // ReferenceError: age is not defined
console.log(undefined == null); // true
Null类型
Null类型同样只有一个值,即特殊值null。逻辑上讲,null值表示一个空指针对象。这也是typeof操作符返回"object"的原因
console.log(typeof null); // "object"
Boolean类型
Boolean类型有两个字面量值: true和false。布尔值变量字面量true和false严格区分大小写,其他大小写混写形式都是有效标识符,但不是布尔值。
在if条件语句或其他流程控制语句中,其他类型会被隐式调用Boolean()(基本包装类型) 函数将其转换为布尔值,不同类型的转换规则:
| 数据类型 | true值 | false值 |
|---|---|---|
| String | 非空字符串 | 空字符串"" |
| Number | 非零数值(包含无穷值) | 0,NaN |
| Object | 任意对象([]、{}等) | null |
| Undefined | —— | undefined |
let isTrue = True; // ReferenceError: True is not defined
let isFalse = false;
console.log(typeof isFalse); // "boolean"
const emptyString = '';
console.log('emptyString', Boolean(emptyString)); // false
console.log('NaN', Boolean(NaN), 'null', Boolean(null)); // false
console.log('对象', Boolean({}), '非零数值', Boolean(Infinity), '非空字符串', Boolean('0')); // true
Number类型
-
进制 不同数值类型相应的有不同的数值字面量格式:十进制、八进制(0开头)、十六进制(0x开头)
-
浮点数
- 浮点数的精确度最高达到17位小数,浮点数小数点后最少要有一位非0的数字
- 缺点: 存在舍入误差;无法测试特定浮点数值
-
值的范围
- 最大值:
Number.MAX_VALUE|,最小值:Number.MIN_VALUE - 超出范围的值: 正无穷
Infinity(Number.POSITIVE_INFINITY)、负无穷-Infinity(Number.NEGATIVE_INFINITY) - 检测方法:
isFinite()返回值:合法范围值为true,超出范围值为false
- 最大值:
-
NaN
- 任何涉及NaN的操作都会返回NaN,NaN与任何值都不相等,包括其自身
- 检测方法: isNaN- 检测是否可转换为数值,返回值: 可以转换为false 不可以转换为true
-
数值转换方法
Number()(基本包装类型)- 布尔值: true转换为1, false转换为0
- 数值: 直接返回
- null: 返回0
- undefined:返回NaN
- 字符串:
- 如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number("1")返回 1,Number("123")返回 123,Number("011")返回 11(忽略前面的零)。
- 如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。
- 如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。
- 如果是空字符串(不包含字符),则返回 0。
- 含除上述情况之外的其他字符,则返回 NaN。
- 对象:调用 valueOf()方法,并按照上述规则转换返回的值。如果转换结果是 NaN,则调用toString()方法,再按照转换字符串的规则转换。toString()方法,再按照转换字符串的规则转换。
let num1 = Number("Hello world!"); // NaN let num2 = Number(""); // 0 let num3 = Number("000011"); // 11 let num4 = Number(true); // 1parseInt(string, radix)
忽略前置空格,直到找到第一个非空格字符, 第一个字符不是数组或符号则返回NaN,如果数字字符 则解析到遇到非数字字符截止
let num1 = parseInt("1234blue"); // 1234 let num2 = parseInt(""); // NaN let num3 = parseInt("0xA"); // 10,解释为十六进制整数 let num4 = parseInt(22.5); // 22 let num5 = parseInt("70"); // 70,解释为十进制值 let num6 = parseInt("0xf"); // 15,解释为十六进制整数 // 传入第二个参数 let num1 = parseInt("10", 2); // 2,按二进制解析 let num2 = parseInt("10", 8); // 8,按八进制解析 let num3 = parseInt("10", 10); // 10,按十进制解析 let num4 = parseInt("10", 16); // 16,按十六进制解析parseFloat(string)
从字符串开头开始检测,解析到字符串末尾或者解析到一个无效的浮点数值为止。
parseFloat()始终忽略开头的0,如果字符串表示整数,则parseFloat()返回整数let num1 = parseFloat("1234blue"); // 1234,按整数解析 let num2 = parseFloat("0xA"); // 0 let num3 = parseFloat("22.5"); // 22.5 let num4 = parseFloat("22.34.5"); // 22.34 let num5 = parseFloat("0908.5"); // 908.5 let num6 = parseFloat("3.125e7"); // 31250000
String类型
字符串特点 字符串是不可变得:一旦创建它们的值就不能变了,要修改某个变量中的字符串值必须先销毁原始字符串,然后将新的字符串保存到该变量 字符串转换方法
toString(): toString()方法可见于数值、布尔值、对象和字符串值。String()- 如果值有toString()方法,则调用该方法(不传参数)并返回结果
- 如果值是null(无toString()方法),则返回"null"
- 如果值是undefined(无toString()方法),则返回"undefined"
let value1 = 10;
let value2 = true;
let value3 = null;
let value4;
console.log(String(value1)); // "10"
console.log(String(value2)); // "true"
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
- 模板字面量 模板字面量保留换行符,可以跨行定义字符串。
// 这个模板字面量在换行符之后有 25 个空格符
let myTemplateLiteral = `first line
second line`;
console.log(myTemplateLiteral.length); // 47
// 这个模板字面量以一个换行符开头
let secondTemplateLiteral = `
first line
second line`;
console.log(secondTemplateLiteral[0] === '\n'); // true
// 这个模板字面量没有意料之外的字符
let thirdTemplateLiteral = `first line
second line`;
console.log(thirdTemplateLiteral);
// first line
// second line
-
字符串插值
模板字面量最常用的一个特性是支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。
- 字符串插值通过在
${}中使用一个 JavaScript 表达式实现:
let exponent = 'second'; // 以前,字符串插值是这样实现的: let interpolatedString = value + ' to the ' + exponent + ' power is ' + (value * value); // 现在,可以用模板字面量这样实现: let interpolatedTemplateLiteral = `${ value } to the ${ exponent } power is ${ value * value }`; console.log(interpolatedString); // 5 to the second power is 25 console.log(interpolatedTemplateLiteral); // 5 to the second power is 25所有插入的值都会使用 toString()强制转型为字符串,而且任何 JavaScript 表达式都可以用于插值。
- 在插值表达式中可以调用函数和方法:
- 字符串插值通过在
function capitalize(word) {
return `${ word[0].toUpperCase() }${ word.slice(1) }`;
}
console.log(`${ capitalize('hello') }, ${ capitalize('world') }!`); // Hello, World!
Symbol类型
复杂数据类型
Object类型
Object实例共有的属性和方法:
constructor:用于创建当前对象的函数。在前面的例子中,这个属性的值就是 Object() 函数。hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如 o.hasOwnProperty("name"))或符号。isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。(第 8 章将详细介绍原型。)propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用(本章稍后讨论的)for-in 语句枚举。与 hasOwnProperty()一样,属性名必须是字符串。toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。toString():返回对象的字符串表示。valueOf():返回对象对应的字符串、数值或布尔值表示。通常与 toString()的返回值相同。