讲解
JavaScript 是动态类型语言:变量本身没有类型,值才有类型,同一个变量可以先装数字再装字符串。这门语言的值分为两大类——原始类型和对象类型。原始类型有七种:number(数字)、string(字符串)、boolean(布尔)、undefined、null、bigint(大整数)、symbol(符号);除此之外的一切——普通对象、数组、函数、日期、正则——都是对象类型。
原始类型和对象类型最本质的区别在于存储和比较方式:原始值是不可变的,按值比较,'a' === 'a' 永远成立;对象是可变的,按引用比较,两个内容一模一样的对象 {} === {} 也是 false,因为它们不是同一个对象。理解这一点是以后避开无数 bug 的基础。
想知道一个值的类型,用 typeof 运算符,它返回类型名字的字符串。typeof 有几个历史遗留的怪癖需要记住:typeof null 是 'object'(一个无法修复的著名 bug),typeof 函数是 'function',而 typeof 数组是 'object'——判断数组要用 Array.isArray()。
示例
console.log(typeof 42); // 'number'
console.log(typeof '你好'); // 'string'
console.log(typeof true); // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof null); // 'object' —— 著名的历史 bug
console.log(typeof 10n); // 'bigint'
console.log(typeof Symbol('id')); // 'symbol'
console.log(typeof {}); // 'object'
console.log(typeof [1, 2]); // 'object' —— 数组也是对象
console.log(typeof function () {}); // 'function'
// 判断数组的正确姿势
console.log('是数组吗:', Array.isArray([1, 2]), Array.isArray('12'));
// 原始值按值比较,对象按引用比较
console.log('值比较:', 42 === 42, 'abc' === 'abc');
console.log('引用比较:', [1] === [1], {} === {});
常见坑
- 用 typeof 判断 null:typeof null === 'object',所以判断 null 要写 value === null,别指望 typeof。
- 用 typeof 判断数组:typeof [] 是 'object'。请用 Array.isArray()。
- 以为变量有固定类型:let x = 1 之后还能 x = '一',合法但极易出 bug。团队协作中不要让一个变量的类型变来变去。
- 混淆 undefined 和 null:undefined 表示「还没赋值」,null 表示「刻意为空」,后面有专门一章展开讲。
小结
七种原始类型加对象类型构成 JavaScript 的全部数据。原始值不可变、按值比较;对象可变、按引用比较。typeof 可粗判类型,但 null 和数组是例外。下一节学习操作这些值的运算符。