一、基本数据类型(Primitive Types,7种)
1. Number - 数字类型
let num1 = 42; // 整数
let num2 = 3.14; // 浮点数
let num3 = Infinity; // 无穷大
let num4 = -Infinity; // 负无穷大
let num5 = NaN; // 非数字 (Not a Number)
let num6 = 0xff; // 十六进制
let num7 = 0b1010; // 二进制
let num8 = 0o777; // 八进制
2. String - 字符串类型
let str1 = 'hello'; // 单引号
let str2 = "world"; // 双引号
let str3 = `template ${str1}`; // 模板字符串
let str4 = "多行\
字符串"; // 多行字符串
3. Boolean - 布尔类型
let bool1 = true;
let bool2 = false;
4. Undefined - 未定义
let x; // 声明但未赋值,值为 undefined
let y = undefined; // 显式赋值为 undefined
5. Null - 空值
let n = null; // 表示空值或无值
6. Symbol - 符号类型 (ES6+)
let sym1 = Symbol('id');
let sym2 = Symbol('id');
console.log(sym1 === sym2); // false,每次创建都是唯一的
// 全局符号
let sym3 = Symbol.for('key'); // 创建或获取全局符号
let sym4 = Symbol.for('key');
console.log(sym3 === sym4); // true
// 内置符号
let obj = {
[Symbol.iterator]: function() { /* ... */ }
};
7. BigInt - 大整数类型 (ES2020+)
let big1 = 9007199254740991n; // 后缀 n
let big2 = BigInt("9007199254740991"); // 构造函数
let big3 = 123n + 456n; // 大整数运算
// 超过 Number.MAX_SAFE_INTEGER (2^53-1)
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
二、引用数据类型(Reference Types,1种)
Object - 对象类型(包含多种子类型)
1. 普通对象 (Object Literal)
let obj = {
name: 'Alice',
age: 25,
sayHello: function() {
console.log('Hello');
}
};
2. 数组 (Array)
let arr = [1, 2, 3, 4];
let arr2 = new Array(1, 2, 3);
3. 函数 (Function)
function sayHello() {
return 'Hello';
}
let func = function() {};
let arrowFunc = () => {};
let asyncFunc = async () => {};
4. 日期 (Date)
let now = new Date();
let specificDate = new Date('2024-01-01');
5. 正则表达式 (RegExp)
let regex = /pattern/gi;
let regex2 = new RegExp('pattern', 'gi');
6. Map
let map = new Map();
map.set('key', 'value');
map.set(1, 'number key');
map.set({}, 'object key');
7. Set
let set = new Set([1, 2, 3, 3, 4]); // [1, 2, 3, 4]
8. WeakMap / WeakSet
let weakMap = new WeakMap(); // 键只能是对象
let weakSet = new WeakSet(); // 值只能是对象
9. 其他内置对象
// Math
Math.PI; Math.random();
// JSON
JSON.parse(); JSON.stringify();
// Promise
let promise = new Promise((resolve, reject) => {});
三、类型检测方法
1. typeof 操作符
console.log(typeof 42); // "number"
console.log(typeof 'hello'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" (历史遗留问题)
console.log(typeof Symbol()); // "symbol"
console.log(typeof 123n); // "bigint"
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof function(){}); // "function"
console.log(typeof /regex/); // "object"
2. instanceof 操作符
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(function(){} instanceof Function); // true
console.log(new Date() instanceof Date); // true
console.log(/regex/ instanceof RegExp); // true
// 注意:基本类型不能用 instanceof 检测
console.log(42 instanceof Number); // false
console.log(new Number(42) instanceof Number); // true
3. Object.prototype.toString
console.log(Object.prototype.toString.call(42)); // "[object Number]"
console.log(Object.prototype.toString.call('hello')); // "[object String]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(Symbol())); // "[object Symbol]"
console.log(Object.prototype.toString.call(123n)); // "[object BigInt]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call(function(){})); // "[object Function]"
4. Array.isArray()
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
四、类型转换
显式类型转换
// 转数字
Number('123'); // 123
parseInt('123px'); // 123
parseFloat('3.14'); // 3.14
+'123'; // 123
// 转字符串
String(123); // "123"
(123).toString(); // "123"
// 转布尔值
Boolean(1); // true
!!1; // true
隐式类型转换
// 字符串拼接
'3' + 4; // "34"
'3' + '4'; // "34"
// 数学运算
'3' - 1; // 2
'3' * '2'; // 6
true + 1; // 2
false + 1; // 1
null + 1; // 1
undefined + 1; // NaN
五、特殊值和特性
1. NaN (Not a Number)
console.log(typeof NaN); // "number"
console.log(NaN === NaN); // false
console.log(isNaN(NaN)); // true
console.log(isNaN('hello')); // true
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('hello')); // false(更精确)
2. null vs undefined
// null 表示空值,undefined 表示未定义
let a; // undefined
let b = null; // null
console.log(a == null); // true
console.log(a === null); // false
console.log(b == undefined); // true(双等号会转换)
console.log(b === undefined); // false
3. == 与 === 的区别
1 == '1'; // true(类型转换)
1 === '1'; // false(严格相等)
0 == false; // true
0 === false; // false
null == undefined; // true
null === undefined; // false
NaN == NaN; // false
NaN === NaN; // false
六、内存管理
栈内存 vs 堆内存
// 基本类型 - 栈内存
let a = 10;
let b = a; // 复制值
a = 20;
console.log(b); // 10
// 引用类型 - 堆内存
let obj1 = { x: 10 };
let obj2 = obj1; // 复制引用
obj1.x = 20;
console.log(obj2.x); // 20
深拷贝与浅拷贝
// 浅拷贝
let obj = { a: 1, b: { c: 2 } };
let shallowCopy = { ...obj };
// 深拷贝
let deepCopy = JSON.parse(JSON.stringify(obj));
// 使用递归或库函数实现完整深拷贝
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
let clone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone;
}
七、ES6+ 新增特性
1. Symbol 的唯一性
const MY_KEY = Symbol();
const obj = {
[MY_KEY]: 'value',
key: 'normal key'
};
console.log(obj[MY_KEY]); // 'value'
console.log(Object.keys(obj)); // ['key'] - Symbol属性不可枚举
2. BigInt 运算
const big1 = 9007199254740991n;
const big2 = 1n;
console.log(big1 + big2); // 9007199254740992n
console.log(big1 * 2n); // 18014398509481982n
// 注意:不能混合 Number 和 BigInt 运算
// console.log(1n + 1); // 错误
console.log(1n + BigInt(1)); // 正确
3. 可选链操作符 ?.
const obj = { a: { b: { c: 1 } } };
console.log(obj?.a?.b?.c); // 1
console.log(obj?.x?.y); // undefined,不会报错
4. 空值合并操作符 ??
const value = null ?? 'default'; // 'default'
const value2 = 0 ?? 'default'; // 0(与 || 不同)
八、最佳实践
- 使用 const 和 let,避免 var
- 优先使用严格相等 ===
- 明确处理 null 和 undefined
- 使用 Number.isNaN() 而不是 isNaN()
- 对象和数组使用深拷贝时注意循环引用
- Symbol 用于创建私有属性
- BigInt 用于大整数运算,注意兼容性
记住:JavaScript 是动态类型语言,但 TypeScript 可以提供静态类型检查。