Skip to content

数据类型

JS 的数据类型可以使用 typeof 操作符来查看;也可以通过 instanceof 来比较值类型

js
typeof 123 // Number
typeof 'str' // String

new Number(1) instanceof Number // true

值类型

基本数据类型的值是不可变的,存储在栈内存中,直接存储值本身

Number(数字型)

包含整数、小数(浮点数),还有特殊值 NaN(Not a Number 的缩写,意思是不是一个数字)、Infinity(无穷大)、-Infinity(负无穷大)

js
let age = 18 // 整数
let price = 99.9 // 浮点数
let notANumber = 'abc' - 1 // NaN
let infiniteNum = 1 / 0 // Infinity

数字字符串和普通数字是可以正常进行运算的

js
function log(params) {
    console.log(`(${typeof params}) ${params}`);
}

log('3' - 2) // 结果 (number) 1
log('3' - '2') // 结果 (number) 1

String(字符串型)

由单引号、双引号或反引号包裹的文本内容,长度可以为 0(空字符串)

js
let name = '张三' // 单引号
let msg = "Hello JS" // 双引号
let html = `我是${name}` // 反引号(支持换行和模板变量)
let emptyStr = '' // 空字符串

其他用法

js
// 可以使用索引来访问某一个位置的字符
let str = "hello world"
console.log(str[0]) // h

// 使用 length 来输出有多少字符
console.log(str.length) // 11

Boolean(布尔型)

只有两个值:true(真)和 false(假)

js
let isAdult = true
let hasMoney = false

对于一下的值类型,都会被认定为假值

  1. false(布尔型本身的假)
  2. 0 / -0 / 0n(数字 0、负 0、BigInt 0)
  3. '' / ""(空字符串,长度为 0)
  4. null(空值)
  5. undefined(未定义)
  6. NaN(非数字)

Undefined(未定义型)

变量声明后未赋值时的默认值,或访问不存在的对象属性时返回该值

js
let num; // 声明但未赋值,值为 undefined
let obj = {};
console.log(obj.age); // 访问不存在的属性,返回 undefined

Null(空值型)

表示数据不存在,是人为主动设置的空值(区别于 undefined 的 “被动未定义”)

js
let emptyObj = null; // 主动声明变量为空

Symbol(符号型)

ES6 新增,用于创建唯一的标识符,解决属性名冲突问题,值是唯一且不可变的

js
let s1 = Symbol('id');
let s2 = Symbol('id');
console.log(s1 === s2); // false(即使描述相同,值也唯一)

BigInt(大整数型)

ES11 新增,用于表示超出 Number 最大值(2^53 - 1)的整数,后缀加 n

js
let bigNum = 9999999999999999999999999999n; // 大整数
let normalNum = 123;
console.log(bigNum + BigInt(normalNum)); // 需转为同类型计算

引用类型

引用数据类型的值是可变的,存储在堆内存中,栈内存只存储指向堆内存的地址(引用)

Object(对象)

JS 中几乎所有复杂类型的基础,结构为键值对(属性名:属性值)

js
let person = {
  name: '李四',
  age: 20,
  isStudent: true
};
person.age = 21; // 引用类型的值可修改

在选取对象的属性的时候如果没法确定需要选取的属性是哪一个可以使用 对象[属性名] 来解决

js
let person = {
  name: '李四',
  age: 20,
  isStudent: true
};

person['age'] = 21;

在赋值的时候如果这个键存在于这个对象中,那么这个键的值会被修改;但是如果对象中不存在这个键那么会在这个对象中创建一个新的键出来用于存放这个值。也就是说对象的属性是可以动态扩展

Array(数组)

特殊的对象,用于存储有序的集合,索引从 0 开始

js
// 方式一
let arr1 = new Array();
arr1[0] = "Saab";
arr1[1] = "Volvo";
arr1[2] = "BMW";
// 方式二
let arr2 = new Array("Saab", "Volvo", "BMW");
// 方式三
let arr3 = ["Saab", "Volvo", "BMW"];

Function(函数)

特殊的对象,可执行的代码块

变量

变量用于存储数据,并可以在程序执行过程中动态更改

  • var:ES5 引入的变量声明方式,具有函数作用域
  • let:ES6 引入的变量声明方式,具有块级作用域
  • const:ES6 引入的常量声明方式,具有块级作用域,且值不可变

var

变量只在声明它的函数内部可访问(只要是在函数内任意地方声明那么整个函数都可以使用),函数外部无法访问

js
function fun() {
    {
        var i = 0
    }
    console.log(i) // 0
}

而且是可以被重复声明的,变量以最后声明的为准

js
var a = 1
var a = 2 // 现在 a 的值为 2

let

块级作用域,不允许在同一作用域重复声明(包括和 var/let 重复)

js
function fun() {
    {
        let a = 0
        console.log(i) // 0
    }
    console.log(i) // undefined
}

const

块级作用域并禁止重复声明(和 let 一致),声明时必须赋值,且指向的内存地址不可变(注意不是 “值不可变”)

js
// 声明时必须赋值
// const g; // 报错:Missing initializer in const declaration
const g = 30;

// 基本类型值不可改(因为内存地址存的是值本身)
// g = 40; // 报错:Assignment to constant variable

// 引用类型(对象/数组)可修改内部值(内存地址没改)
const obj = { name: '张三' };
obj.name = '李四'; // 不报错!只是修改对象内部属性,地址没改
console.log(obj.name); // 李四

const arr = [1, 2, 3];
arr.push(4); // 不报错!数组地址没改,只是内部元素变了
console.log(arr); // [1,2,3,4]