JavaScript typeof, null, 和 undefined
JavaScripttypeof,null, 和undefined深度解析这三个概念是 JavaScript 类型系统的基石也是面试和实际开发中最容易混淆的地方。特别是typeof null的“历史遗留问题”是理解 JS 类型系统的关键。1.undefined未定义的值含义undefined表示**“变量已声明但尚未赋值”**。它代表“缺失的值”。何时出现变量声明但未赋值leta;console.log(a);// undefined函数没有返回值functionnoReturn(){}console.log(noReturn());// undefined访问对象不存在的属性constobj{name:Alice};console.log(obj.age);// undefined函数参数未传递functiongreet(name){console.log(name);}greet();// undefined特性undefined是全局对象的属性但在严格模式下不可重新赋值。typeof undefined返回undefined。最佳实践检查变量是否存在时推荐使用 undefined或 null后者同时匹配 null。2.null空对象指针含义null表示**“有意为空”或“没有对象”。它是一个对象类型的空值**。何时出现手动赋值letusernull;// 表示用户当前未登录或数据为空函数返回“无结果”functionfindUser(id){// 如果没找到返回 null 而不是 undefinedreturnnull;}特性typeof null返回object这是 JS 的历史 Bug详见下文。null是原始值Primitive但在类型判断上被归类为对象。最佳实践当你想明确表示“这里应该有个对象但现在没有”时使用null。3.typeof运算符作用typeof用于返回操作数的数据类型字符串。语法typeofoperand// 或typeof(operand)返回值对照表值typeof返回结果说明数字 (123)number包括整数和浮点数字符串 (hello)string布尔值 (true)booleanundefinedundefinednullobject历史遗留 Bug对象 ({})object数组 ([])object注意数组也是对象函数 (function(){})function特例SymbolsymbolES6 新增BigIntbigintES2020 新增未声明的变量undefined不会报错关键示例console.log(typeof42);// numberconsole.log(typeofHello);// stringconsole.log(typeoftrue);// booleanconsole.log(typeofundefined);// undefinedconsole.log(typeofnull);// object -- 著名的 Bugconsole.log(typeof{});// objectconsole.log(typeof[]);// object -- 数组也是对象console.log(typeoffunction(){});// functionconsole.log(typeofSymbol(id));// symbolconsole.log(typeof10n);// bigint// 未声明的变量console.log(typeofnotExist);// undefined (不会抛出 ReferenceError)4. 核心难点为什么typeof null是object历史原因在 JavaScript 的最初版本1995年中类型信息存储在值的底层表示中。值的底层是一个 32 位整数。类型标签Type Tag存储在低 3 位。000被用来表示Object类型。null在底层表示为全 0 的机器码0x00000000。因此当typeof检查null时它看到低 3 位是000误以为它是一个对象。为什么不能修复由于typeof null object已经被广泛使用在数百万行代码中如果现在修改它会导致大量现有代码崩溃。因此ECMAScript 委员会决定保留这个 Bug以保持向后兼容。如何正确判断null由于typeof无法区分null和对象必须使用严格相等constvalnull;// ❌ 错误无法区分 null 和对象if(typeofvalobject){// 这里会进入但 val 可能是 null 也可能是 {}}// ✅ 正确显式检查 nullif(valnull){console.log(这是 null);}// ✅ 或者使用 Object.prototype.toString (最严谨)if(Object.prototype.toString.call(val)[object Null]){console.log(这是 null);}5.nullvsundefined区别与使用场景特性undefinednull含义未定义、缺失、未初始化有意为空、空对象指针来源引擎自动赋值开发者手动赋值类型undefinedobject(typeof 结果)相等性undefined null为trueundefined null为false使用场景变量声明未赋值、函数无返回值清空对象引用、表示“无数据”代码对比// 场景 1变量初始化leta;// 自动为 undefinedletbnull;// 手动设为 null// 场景 2函数返回functiongetAge(){// 如果没算出年龄返回 undefined (默认)}functiongetUser(id){// 如果用户不存在返回 null (明确表示“查无此人”)returnnull;}// 场景 3对象属性constuser{};console.log(user.name);// undefined (属性不存在)user.namenull;// 属性存在但值为空console.log(user.name);// null6. 实用技巧与最佳实践技巧 1使用 null同时检查null和undefined在 JavaScript 中null undefined返回true而null undefined返回false。利用这个特性可以简洁地检查“值是否为空”functionprocessValue(val){// 如果 val 是 null 或 undefined都视为无效if(valnull){console.log(值无效);return;}console.log(值有效:,val);}processValue(undefined);// 值无效processValue(null);// 值无效processValue(0);// 值有效: 0processValue();// 值有效: processValue(false);// 值有效: false注意这只会匹配 null 和 undefined不会匹配 0、空字符串或 false。技巧 2使用??(空值合并运算符)ES2020 引入的??运算符专门用于处理null和undefined。constnamenull;constdisplayNamename??默认用户;// 输出 默认用户constcount0;constdisplayCountcount??10;// 输出 0 (因为 0 不是 null/undefined)对比||运算符0 || 10会返回10因为0是假值。??更精准。技巧 3判断是否为对象排除 null由于typeof null是object判断对象时需要排除 nullfunctionisObject(val){returnval!nulltypeofvalobject;}console.log(isObject({}));// trueconsole.log(isObject([]));// trueconsole.log(isObject(null));// falseconsole.log(isObject(123));// false7. 总结undefined系统自动赋值表示“未定义”。typeof返回undefined。null手动赋值表示“空对象”。typeof返回object历史 Bug。typeof是判断类型的首选工具。对null的判断失效需配合 null。对数组返回object需配合Array.isArray()。判断空值严格区分val null或val undefined。同时检查val null或使用val ?? default。