我想知道JavaScript中null和undefined之间的区别。


当前回答

这两个特殊值都表示为空状态。

主要区别在于undefined表示尚未初始化的变量的值,而null表示有意缺少对象。

但是,变量编号已定义,未分配初始值:

let number;
number; // => undefined

number变量未定义,这明显表示变量未初始化当访问不存在的对象属性时,会发生相同的未初始化概念:

const obj = { firstName: 'Dmitri' };
obj.lastName; // => undefined

由于obj中不存在lastName属性,JavaScript正确地将obj.lastName计算为undefined。

在其他情况下,您知道变量需要保存对象或函数以返回对象。但由于某些原因,您无法实例化对象。在这种情况下,null是丢失对象的有意义的指示符。

例如,clone()是一个克隆普通JavaScript对象的函数。该函数应返回一个对象:

function clone(obj) {
  if (typeof obj === 'object' && obj !== null) {
    return Object.assign({}, obj);
  }
  return null;
}
clone({name: 'John'}); // => {name: 'John'}
clone(15);             // => null
clone(null);           // => null

然而,clone()可以用非对象参数调用:15或null(或通常为原始值,null或undefined)。在这种情况下,该函数无法创建克隆,因此它返回null-缺少对象的指示符。

typeof运算符区分两个值:

typeof undefined; // => 'undefined'
typeof null;      // => 'object'

严格质量运算符==正确区分undefined和null:

let nothing = undefined;
let missingObject = null;
nothing === missingObject; // => false

其他回答

undefined和null之间的含义差异是JavaScript设计的一个意外,大多数时候这并不重要。如果你真的需要关注这些价值观,我建议你将它们视为可以互换的。

来自Elquent Javascript书

请仔细阅读以下内容。它应该可以消除您对JavaScript中null和undefined之间区别的所有疑虑。此外,您可以在答案末尾使用效用函数来获取更具体的变量类型。

在JavaScript中,我们可以有以下类型的变量:

未声明的变量已声明但未分配的变量未定义文字赋值的变量赋值为文本null的变量变量分配了除未定义或null以外的任何值

以下逐一解释了每种情况:

未声明的变量只能使用返回字符串“undefined”的typeof运算符进行检查不能用松散相等运算符(==undefined)检查,更不用说严格相等运算符(===undefineed),以及if语句和三元运算符(?:)-这些抛出引用错误已声明但未分配的变量typeof返回字符串“undefined”==检查null返回true==未定义的检查返回true==检查null返回false==未定义的检查返回trueif语句和三元运算符(?:)是否错误未定义文字赋值的变量这些变量与已声明但未分配的变量完全相同。赋值为文本null的变量typeof返回字符串“object”==检查null返回true==未定义的检查返回true==检查null返回true==检查未定义返回falseif语句和三元运算符(?:)是否错误变量分配了除未定义或null以外的任何值typeof返回以下字符串之一:“bigint”、“boolean”、“function”、“number”、“object”、“string”、“symbol”

以下提供了正确检查变量类型的算法:

获取变量的类型,如果它不是“object”,则返回它检查null,因为typeof null也返回“object”使用switch语句对Object.protype.toString.call(o)求值,以返回更精确的值。Object的toString方法为本机/主机对象返回类似“[Object ConstructorName]”的字符串。对于所有其他对象(用户定义的对象),它始终返回“[object object]”如果最后一部分是这种情况(变量的字符串化版本为“[objectObject]”),并且参数returnConstructorBoolean为真,则它将尝试通过对其进行字符串化并从中提取名称来获取构造函数的名称。如果无法访问构造函数,将照常返回“object”。如果字符串不包含其名称,则返回“匿名”

(支持ECMAScript 2020之前的所有类型)

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) {
    // Value types: 6
    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'

    // Error types: 7
    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'

    // Indexed Collection and Helper types: 13
    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'

    // Keyed Collection types: 2
    case '[object Map]':               return 'map'
    case '[object WeakMap]':           return 'weakmap'

    // Set types: 2
    case '[object Set]':               return 'set'
    case '[object WeakSet]':           return 'weakset'

    // Operation types: 3
    case '[object RegExp]':            return 'regexp'
    case '[object Proxy]':             return 'proxy'
    case '[object Promise]':           return 'promise'

    // Plain objects
    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-它是一个赋值值,与变量一起使用以表示任何值(它是对象)。

undefined-它是一个没有赋值的变量,所以JavaScript会给它赋值一个undefineed(它是一种数据类型)。

未声明-如果根本没有创建变量,则称为未声明。

在JavasScript中有5种基本数据类型:String、Number、Boolean、null和undefined。我将尝试用一些简单的例子来解释。

假设我们有一个简单的函数

 function test(a) {
     if(a == null) {
        alert("a is null");
     } else {
        alert("The value of a is " + a);
     }
  }

此外,在上述函数中,if(a==null)与if(!a)相同。

现在,当我们调用此函数而不传递参数

test(); // will alert "a is null";
test(4); // will alert "The value of a is " + 4;

also

var a;
alert(typeof a);

这将给出未定义的;我们声明了一个变量,但没有为该变量赋值;

但如果我们写

var a = null;
alert(typeof a); // will give alert as object

所以null是一个对象。在某种程度上,我们为“a”分配了一个空值

在Javascript中,null是一个空值或不存在的值,必须赋值。但Undefined表示已声明变量,但未定义值。

let a = null;  
console.log(a);    // null
let b;         
console.log(b);    // undefined

在JS中,null和undefined都是原始值。您还可以查看以下代码行

console.log(typeof null); //Object
console.log(typeof undefined); //undefined
console.log(10+null); // 10
console.log(10+undefined); //NaN