JavaScript 中的 null 和 undefined 有什么区别?

IT技术 javascript null undefined
2021-01-23 06:39:26

我想知道JavaScriptnullundefinedJavaScript之间的区别

6个回答

在 JavaScript 中,undefined表示变量已经声明但尚未赋值,例如:

var testVar;
alert(testVar); //shows undefined
alert(typeof testVar); //shows undefined

null是一个赋值。可以将它分配给变量作为无值的表示:

var testVar = null;
alert(testVar); //shows null
alert(typeof testVar); //shows object

从前面的示例中,很明显undefinednull是两种不同的类型:undefined是类型本身(未定义),而null是对象。

null === undefined // false
null == undefined // true
null === null // true

null = 'value' // ReferenceError
undefined = 'value' // 'value'
Nir O. 的评论非常重要。如果我想要一个开头没有值的变量,我会写“... = null”,例如“myvar = null”。这样 - 当我输入错误“if (myxar == null) {...}”时 - 不会执行 if 块。我没有 undefined 这个优势: myvar = undefined; 米瓦尔 = 4; if (typeof myxar == "undefined") { ...}
2021-03-15 06:39:26
所以基本上空值意味着一个变量已被显式设置为 (no value = null) 或已被初始化并定义为空。而未定义的意思。它可能从未被初始化,或者它从未被定义。
2021-03-18 06:39:26
@Wolfgang Adamec,无错误编程与错误类型无关。
2021-03-31 06:39:26
变量也可能根本没有定义。例如:console.log(typeof(abc)); 不明确的
2021-04-03 06:39:26
引用来自 Professional JS For Web Developers (Wrox) 一书中的引用:“您可能想知道为什么 typeof 运算符为 null 值返回 'object'。这实际上是原始 JavaScript 实现中的一个错误,然后被复制到 ECMAScript 中。今天,将 null 视为对象的占位符是合理的,尽管从技术上讲,它是一个原始值。”
2021-04-09 06:39:26

区别可以用卫生纸架来解释:

  • 非零值就像一个拿着一卷卫生纸的支架,而管子上还有纸巾。

  • 零值就像一个带有空卫生纸管的支架。

  • 空值就像一个甚至没有组织管的支架。

  • 未定义的值类似于缺少持有者本身。

@Vega 不幸的是,不,我不记得我是从 imgur.com 上的某个地方获得的,这可能来自转贴,而不是原始来源。甚至这里的嵌入式链接都没有提供任何发布此版本的线索,所以我也无法真正搜索它。
2021-03-10 06:39:26
@SebastianNorr“我不记得我从 imgur.com 上的某个地方以外的地方得到它”-> 是这样undefined还是null在那种情况下?
2021-03-18 06:39:26
@Erowlin它更接近于存在,null因为我记得图像来自imgur,所以它并不是完全未知的。undefined会更喜欢“我不知道它是从哪里来的。”
2021-03-28 06:39:26
你能包括图片来源的归属吗?
2021-04-02 06:39:26
let toiletPaperIn2020 = undefined;
2021-04-03 06:39:26

我从这里选择了这个

未定义值是在变量尚未赋值时使用的原始值。

空值是一个原始值,表示空、空或不存在的引用。

当你通过 var 声明一个变量并且不给它一个值时,它的值将是 undefined。就其本身而言,如果您尝试使用 WScript.Echo() 或 alert() 这个值,您将看不到任何内容。但是,如果您向其附加一个空白字符串,那么它会突然出现:

var s;
WScript.Echo(s);
WScript.Echo("" + s);

您可以声明一个变量,将其设置为空,并且行为是相同的,只是您会看到打印出“空”与“未定义”。这确实是一个很小的差异。

您甚至可以将未定义的变量与 null 进行比较,反之亦然,条件将为真:

undefined == null
null == undefined

然而,它们被认为是两种不同的类型。虽然 undefined 是一种完全属于它自己的类型,但 null 被认为是一个特殊的对象值。您可以通过使用 typeof() 来查看这一点,它返回一个表示变量一般类型的字符串:

var a;
WScript.Echo(typeof(a));
var b = null;
WScript.Echo(typeof(b));

运行上述脚本将产生以下输出:

undefined
object

不管它们是不同的类型,如果您尝试访问其中任何一个的成员,它们的行为仍然相同,例如,它们将抛出异常。使用 WSH,您会看到可怕的“'varname' 为空或不是对象”,如果您很幸运的话(但这是另一篇文章的主题)。

您可以明确地将变量设置为未定义,但我强烈建议您不要这样做。我建议只将变量设置为 null 并为您忘记设置的东西保留未定义的值。同时,我真的鼓励您始终设置每个变量。JavaScript 的作用域链不同于 C 风格的语言,即使是老手也容易混淆,将变量设置为 null 是防止基于它的错误的最佳方法。

您将看到 undefined 弹出的另一个实例是使用删除运算符时。我们这些来自 C 世界的人可能会错误地将此解释为破坏一个物体,但事实并非如此。此操作的作用是从数组中删除下标或从对象中删除成员。对于数组,它不会影响长度,而是现在认为下标未定义。

var a = [ 'a', 'b', 'c' ];
delete a[1];
for (var i = 0; i < a.length; i++)
WScript.Echo((i+".) "+a[i]);

上面脚本的结果是:

0.) a
1.) undefined
2.) c

读取从未存在的下标或成员时,您也会得到 undefined 返回。

null 和 undefined 之间的区别在于:JavaScript 永远不会将任何内容设置为 null,这通常是我们所做的。虽然我们可以将变量设置为 undefined,但我们更喜欢 null 因为它不是我们曾经做过的事情。当您进行调试时,这意味着设置为 null 的任何内容都是您自己做的,而不是 JavaScript。除此之外,这两个特殊值几乎是等效的。

值得注意的是,虽然这条评论在 11 年是正确的,但随着可选函数参数的出现、类型检查系统如 Flow 的出现以及 React 的普及(所有这些都非常不同地对待 undefined 和 null),旧的智慧通常使用 null 而不是 undefined 不再如此严格。在许多情况下,您希望显式使用默认值(例如,对于可选参数或可选 React 道具), undefined 实际上比 null 更可取。
2021-03-11 06:39:26
真的是一个很好的答案。但要指出的是,当您检查“undefined == null”时,类型检查并不严格。因此它返回“真”。如果你勾选“undefined === null”,它会返回false。
2021-03-20 06:39:26

null是一个特殊的关键字,表示没有值。

将其视为一个值,例如:

  • “foo”是字符串,
  • true 是布尔值,
  • 1234是数字,
  • null 未定义。

undefined属性表示变量还没有被赋值,包括 null 。喜欢

var foo;

定义的空变量是null数据类型undefined


它们都代表一个 没有值的变量的值

null不代表字符串没有值-空与字符串


喜欢

var a = ''; 
console.log(typeof a); // string 
console.log(a == null); //false 
console.log(a == undefined); // false 

现在如果

var a;
console.log(a == null); //true
console.log(a == undefined); //true 

var a; 
console.log(a === null); //false 
console.log(a === undefined); // true

所以每个人都有自己的使用方式

undefined使用它来比较变量数据类型

null使用它来清空变量的值

var a = 'javascript';
a = null ; // will change the type of variable "a" from string to object 
null绝对是一种数据类型: msdn.microsoft.com/en-us/library/ie/7wkd9z69(v=vs.94).aspx 。在 ECMAScript 的早期版本中typeof null返回object是一个众所周知的有记录的错误,该错误一直保持向后兼容性。在评论中实际发布的链接在页面中间显示“typeof null // object(ECMAScript 中的错误,应该为 null)”!所以请在评论反对票之前展示一些搜索工作
2021-03-13 06:39:26
直到今天,“null 未定义”仍然是错误的。
2021-03-17 06:39:26
定义相互矛盾:“缺乏value”与“尚未分配value”。不是一样吗?
2021-03-29 06:39:26
null 也是一种数据类型。undefined 和 null 都是数据类型和值
2021-03-31 06:39:26
我不同意这个答案。Null 和 undefined 都是不同的数据类型。null 是 null 类型,undefined 是 undefined 类型。只有在使用真运算符 (==) 时,我们才能看到 javascript 说它为真,但严格比较 (===) 会产生假。
2021-04-03 06:39:26

请仔细阅读以下内容。它应该消除您对JavaScriptnullundefinedJavaScript之间差异的所有疑虑此外,您可以使用本答案末尾的实用程序函数来获取更具体类型的变量。

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

  1. 未声明的变量
  2. 已声明但未分配的变量
  3. 用文字赋值的变量 undefined
  4. 用文字赋值的变量 null
  5. 分配有除undefined以外的任何变量的变量null

下面对每一种情况进行一一说明:

  1. 未声明的变量

    • 只能使用typeof返回字符串'undefined'运算符进行检查
    • 无法使用松散相等运算符 ( == undefined)进行检查,更不用说严格相等运算符 ( === undefined)
      以及if 语句三元运算符( ? :) — 这些会抛出引用错误
  2. 已声明但未分配的变量

    • typeof返回字符串“未定义”
    • ==检查null退货true
    • ==检查undefined退货true
    • ===检查null退货false
    • ===检查undefined退货true
    • if 语句三元运算符( )? :
  3. 用文字undefined
    赋值的变量 这些变量的处理方式与已声明但未分配的变量完全相同

  4. 用文字赋值的变量 null

    • typeof返回字符串“对象”
    • ==检查null退货true
    • ==检查undefined退货true
    • ===检查null退货true
    • ===检查undefined退货false
    • if 语句三元运算符( )? :
  5. 分配有除undefined以外的任何变量的变量null

    • typeof 返回以下字符串之一:'bigint''boolean''function''number''object''string''symbol'

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

  1. 获取typeof我们的变量并在它不是“对象”时返回它
  2. 检查null,作为typeof null回报“对象”,以及
  3. 使用 switch 语句评估Object.prototype.toString.call(o)以返回更精确的值。Object'stoString方法返回看起来像'[object ConstructorName]'的本地/宿主对象的字符串对于所有其他对象(用户定义的对象),它总是返回'[object Object]'
  4. 如果最后一部分是这种情况(变量的字符串化版本是'[object Object]')并且参数returnConstructorBooleantrue,它将尝试通过toString-ing 并从那里提取名称来获取构造函数的名称。如果无法访问构造函数,则像往常一样返回'object'如果字符串不包含其名称,则返回'anonymous'

(支持 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)
  }
}