JavaScript中null和undefined的区别
技术背景
在JavaScript中,null
和 undefined
都用于表示值的缺失,但它们有着不同的含义和用途。理解它们之间的区别对于编写高质量的JavaScript代码至关重要。
实现步骤
1. 理解undefined
undefined
表示变量已声明但尚未赋值,或者函数没有返回值,或者访问对象中不存在的属性。
1 2 3 4 5 6 7 8 9 10 11 12
| var testVar; console.log(testVar); console.log(typeof testVar);
function noReturnValue() {} console.log(noReturnValue());
const obj = { name: 'John' }; console.log(obj.age);
|
2. 理解null
null
是一个赋值值,表示变量被有意设置为没有值。
1 2 3
| var testVar = null; console.log(testVar); console.log(typeof testVar);
|
3. 比较null
和undefined
虽然 null
和 undefined
在宽松相等比较(==
)时返回 true
,但它们是不同的类型,在严格相等比较(===
)时返回 false
。
1 2 3
| console.log(null === undefined); console.log(null == undefined); console.log(null === null);
|
核心代码
检查不同类型变量的表现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
var declaredButUnassigned; console.log(typeof declaredButUnassigned); console.log(declaredButUnassigned == null); console.log(declaredButUnassigned == undefined); console.log(declaredButUnassigned === null); console.log(declaredButUnassigned === undefined);
var assignedUndefined = undefined; console.log(typeof assignedUndefined); console.log(assignedUndefined == null); console.log(assignedUndefined == undefined); console.log(assignedUndefined === null); console.log(assignedUndefined === undefined);
var assignedNull = null; console.log(typeof assignedNull); console.log(assignedNull == null); console.log(assignedNull == undefined); console.log(assignedNull === null); console.log(assignedNull === undefined);
|
自定义类型检查函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| function TypeOf(o, returnConstructorBoolean) { const type = typeof o;
if (type !== 'object') return type; if (o === null) return 'null';
const toString = Object.prototype.toString.call(o);
switch (toString) { case '[object BigInt]': return 'bigint'; case '[object Boolean]': return 'boolean'; case '[object Date]': return 'date'; case '[object Number]': return 'number'; case '[object String]': return 'string'; case '[object Symbol]': return 'symbol';
case '[object Error]': return 'error'; case '[object EvalError]': return 'evalerror'; case '[object RangeError]': return 'rangeerror'; case '[object ReferenceError]': return'referenceerror'; case '[object SyntaxError]': return'syntaxerror'; case '[object TypeError]': return 'typeerror'; case '[object URIError]': return 'urierror';
case '[object Array]': return 'array'; case '[object Int8Array]': return 'int8array'; case '[object Uint8Array]': return 'uint8array'; case '[object Uint8ClampedArray]': return 'uint8clampedarray'; case '[object Int16Array]': return 'int16array'; case '[object Uint16Array]': return 'uint16array'; case '[object Int32Array]': return 'int32array'; case '[object Uint32Array]': return 'uint32array'; case '[object Float32Array]': return 'float32array'; case '[object Float64Array]': return 'float64array'; case '[object ArrayBuffer]': return 'arraybuffer'; case '[object SharedArrayBuffer]': return'sharedarraybuffer'; case '[object DataView]': return 'dataview';
case '[object Map]': return 'map'; case '[object WeakMap]': return 'weakmap';
case '[object Set]': return 'set'; case '[object WeakSet]': return 'weakset';
case '[object RegExp]': return'regexp'; case '[object Proxy]': return 'proxy'; case '[object Promise]': return 'promise';
case '[object Object]': if (!returnConstructorBoolean) return type;
const _prototype = Object.getPrototypeOf(o); if (!_prototype) return type;
const _constructor = _prototype.constructor; if (!_constructor) return type;
const matches = Function.prototype.toString.call(_constructor).match(/^function\s*([^\s(]+)/); return matches? matches[1] : 'anonymous';
default: return toString.split(' ')[1].slice(0, -1); } }
|
最佳实践
- 使用
null
:当你明确知道某个变量或对象应该没有值时,使用 null
。例如,初始化一个对象变量,但还没有实际的对象可以赋值时。
1 2 3
| let myObject = null;
myObject = { name: 'Example' };
|
- 使用
undefined
:让JavaScript自动为未赋值的变量赋予 undefined
值,避免手动将变量设置为 undefined
。在函数中,如果没有合适的返回值,自然返回 undefined
。
常见问题
1. null
和 undefined
在数值上下文中的表现不同
1 2 3 4 5 6 7 8 9 10 11 12 13
| var a; var b = null;
console.log(a === undefined); console.log(b === null); console.log(a == b); console.log(a >= b); console.log(a >= a); console.log(isNaN(a)); console.log(1 * a); console.log(b >= b); console.log(isNaN(b)); console.log(1 * b);
|
null
在算术表达式或数值比较中表现得像 0
,而 undefined
会变成 NaN
。
2. undefined
可以被覆盖,而 null
是保留关键字
1 2 3 4
| var undefined = 'foo'; console.log(undefined);
|
不建议覆盖 undefined
,因为这会导致代码的可读性和可维护性变差。