What is the difference between null and undefined in JavaScript?
我想知道JavaScript中
在javascript中,
1 2 3 | var TestVar; alert(TestVar); //shows undefined alert(typeof TestVar); //shows undefined |
1 2 3 | var TestVar = null; alert(TestVar); //shows null alert(typeof TestVar); //shows object |
从前面的例子中可以清楚地看出,
1 2 3 | null === undefined // false null == undefined // true null === null // true |
和
1 2 | null = 'value' // ReferenceError undefined = 'value' // 'value' |
我从这里选的这个
The undefined value is a primitive value used when a variable has not
been assigned a value.The null value is a primitive value that represents the null, empty,
or non-existent reference.
当您通过var声明一个变量并且不给它一个值时,它的值将是未定义的。如果您尝试wscript.echo()或alert()这个值,您将看不到任何内容。但是,如果在它后面附加一个空字符串,那么它会突然出现:
1 2 3 | var s; WScript.Echo(s); WScript.Echo("" + s); |
您可以声明一个变量,将其设置为空,并且行为是相同的,除了您将看到打印出的"空"和"未定义"之外。这确实是一个小小的区别。
甚至可以将未定义的变量与空变量进行比较,反之亦然,条件将为真:
1 2 | undefined == null null == undefined |
然而,它们被认为是两种不同的类型。虽然undefined本身是一个类型all,但NULL被认为是一个特殊的对象值。通过使用type of()可以看到这一点,type of()返回一个表示变量常规类型的字符串:
1 2 3 4 | var a; WScript.Echo(typeof(a)); var b = null; WScript.Echo(typeof(b)); |
运行上述脚本将导致以下输出:
1 2 | undefined object |
不管它们是不同的类型,如果您试图访问其中一个成员,它们的行为仍然相同,例如,它们将抛出一个异常。有了wsh,你会看到可怕的"'varname'是空的或者不是一个对象",如果你很幸运的话(但这是另一篇文章的主题)。
您可以明确地将变量设置为未定义,但我强烈建议不要这样做。我建议只将变量设置为空,并为忘记设置的内容保留未定义的值。同时,我真的鼓励你总是设置每一个变量。JavaScript的作用域链不同于C风格的语言,即使是经验丰富的程序员也很容易混淆,将变量设置为空是防止基于它的错误的最佳方法。
另一个您将看到未定义弹出窗口的实例是使用删除运算符时。我们这些来自C世界的人可能会错误地把这理解为摧毁一个物体,但事实并非如此。此操作的作用是从数组中删除下标或从对象中删除成员。对于数组,它不影响长度,但下标现在被认为是未定义的。
1 2 3 4 | var a = [ 'a', 'b', 'c' ]; delete a[1]; for (var i = 0; i < a.length; i++) WScript.Echo((i+".)"+a[i]); |
上述脚本的结果是:
1 2 3 | 0.) a 1.) undefined 2.) c |
在读取从未存在的下标或成员时,也会得到未定义的返回。
空值和未定义值的区别在于:javascript永远不会将任何内容设置为空值,这通常是我们要做的。虽然我们可以将变量设置为未定义,但我们更喜欢空值,因为它从来没有为我们做过。当您调试时,这意味着任何设置为空的东西都是您自己做的,而不是JavaScript。除此之外,这两个特殊值几乎相等。
空是一个特殊的关键字,表示缺少值。
把它当作一个价值,比如:
- "foo"是字符串,
- 真是布尔值,
- 1234是数字,
- 未定义空值。
Undefined属性表示还没有为变量分配包含空值的值。喜欢
1 | var foo; |
定义的空变量是
它们都表示一个变量的值,但没有值
和
喜欢
1 2 3 4 | var a = ''; console.log(typeof a); // string console.log(a == null); //false console.log(a == undefined); // false |
现在如果
1 2 3 | var a; console.log(a == null); //true console.log(a == undefined); //true |
但是
1 2 3 | var a; console.log(a === null); //false console.log(a === undefined); // true |
所以每个人都有自己的使用方法
未定义使用它比较变量数据类型
空使用它来清空变量的值
1 2 | var a = 'javascript'; a = null ; // will change the type of variable"a" from string to object |
空:变量没有值;未定义:变量本身没有值;
..其中变量是与值关联的符号名。
JS可以用空值隐式初始化新声明的变量,但它不能。
请仔细阅读以下内容。它将消除你对在JavaScript中,空值和未定义值之间的差异。您还可以使用下面给出的实用程序函数来精确地确定类型。
在JavaScript中,我们可以有以下类型的变量。
下面逐一解释这些案例
未声明的变量:对于未声明的变量,以下值为true
- 只能由返回字符串"undefined"的typeof()检查
- 不能用==或==或if或条件运算符检查?(引发引用错误)
已声明但未分配的变量
- typeof返回字符串"undefined"
- ==检查为空返回真
- ==用未定义的返回值检查为真
- ===检查为空返回假
- ===检查未定义的返回值为真
- if或条件运算符?返回错误
未定义字面赋值的变量:这些变量被视为已声明但未分配的变量。
以文本空值分配的变量
- typeof返回字符串"object"
- ==检查为空返回真
- ==用未定义的返回值检查为真
- ===检查为空返回真
- ===检查未定义的返回值为假
- if或条件运算符?返回错误
变量被赋予了除未定义或空之外的任何内容
- typeof返回以下字符串之一:"string"、"number"、"boolean"、"function"、"object"、"symbol"
下面提供了对变量进行正确类型检查的算法:
您还可以使用以下实用程序函数来确定类型。目前,它支持所有ECMA 262 2017类型。
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 | function TypeOf(o,bReturnConstructor) { if(typeof o==='undefined') return 'undefined' if(o===null) return 'null' if(typeof o!=='object') return typeof o var type=Object.prototype.toString.call(o) switch(type) { //Value types:4 case '[object Number]': type='number';break; case '[object String]': type='string';break; case '[object Boolean]': type='boolean';break; case '[object Date]': type='date';break; //Error Types:7 case '[object Error]': type='error';break; case '[object EvalError]': type='evalerror';break; case '[object RangeError]': type='rangeerror';break; case '[object ReferenceError]': type='referenceerror';break; case '[object SyntaxError]': type='syntaxerror';break; case '[object TypeError]': type='typeerror';break; case '[object URIError]': type='urierror';break; //Indexed Collection and Helper Types:13 case '[object Array]': type='array';break; case '[object Int8Array]': type='int8array';break; case '[object Uint8Array]': type='uint8array';break; case '[object Uint8ClampedArray]': type='uint8clampedarray';break; case '[object Int16Array]': type='int16array';break; case '[object Uint16Array]': type='uint16array';break; case '[object Int32Array]': type='int32array';break; case '[object Uint32Array]': type='uint32array';break; case '[object Float32Array]': type='float32array';break; case '[object Float64Array]': type='float64array';break; case '[object ArrayBuffer]': type='arraybuffer';break; case '[object SharedArrayBuffer]': type='sharedarraybuffer';break; case '[object DataView]': type='dataview';break; //Keyed Collection Types:2 case '[object Map]': type='map';break; case '[object WeakMap]': type='weakmap';break; //Set Types:2 case '[object Set]': type='set';break; case '[object WeakSet]': type='weakset';break; //Operation Types case '[object RegExp]': type='regexp';break; case '[object Proxy]': type='proxy';break; case '[object Promise]': type='promise';break; case '[object Object]': type='object'; if(bReturnConstructor && o.constructor) type=o.constructor.toString().match(/^function\s*([^\s(]+)/)[1]; break; default: type=type.split(' ')[1] type=type.substr(0,type.length-1) } return type } |
我来解释一下
1-
2-
3-
空和未定义是两种不同的对象类型,它们具有以下共同点:
- 两者只能保存一个值,分别为空和未定义;
- 两者都没有属性或方法,并且尝试读取其中任何一个的任何属性都将导致运行时错误(对于所有其他对象,如果尝试读取不存在的属性,则会得到未定义的值);
- 值null和undefined被
== 和!= 运算符视为彼此相等,而不是其他值。
但相似之处到此为止。有一次,在实现关键字"空"和"未定义"的方式上存在根本区别。这并不明显,但请考虑以下示例:
1 2 | var undefined ="foo"; WScript.Echo(undefined); // This will print: foo |
未定义,nan和infinity只是预初始化的"superglobal"变量的名称-它们在运行时初始化,可以被具有相同名称的普通全局或局部变量覆盖。
现在,让我们用NULL来尝试同样的事情:
1 2 | var null ="foo"; // This will cause a compile-time error WScript.Echo(null); |
哎呀!空、真和假是保留关键字-编译器不允许将它们用作变量或属性名。
另一个区别是未定义是一个基元类型,而空是一个对象类型(表示对象引用的缺失)。考虑以下事项:
1 2 3 4 5 6 | WScript.Echo(typeof false); // Will print: boolean WScript.Echo(typeof 0); // Will print: number WScript.Echo(typeof""); // Will print: string WScript.Echo(typeof {}); // Will print: object WScript.Echo(typeof undefined); // Will print: undefined WScript.Echo(typeof null); // (!!!) Will print: object |
此外,在数字上下文中处理空值和未定义值的方式也有一个重要区别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var a; // declared but uninitialized variables hold the value undefined WScript.Echo(a === undefined); // Prints: -1 var b = null; // the value null must be explicitly assigned WScript.Echo(b === null); // Prints: -1 WScript.Echo(a == b); // Prints: -1 (as expected) WScript.Echo(a >= b); // Prints: 0 (WTF!?) WScript.Echo(a >= a); // Prints: 0 (!!!???) WScript.Echo(isNaN(a)); // Prints: -1 (a evaluates to NaN!) WScript.Echo(1*a); // Prints: -1.#IND (in Echo output this means NaN) WScript.Echo(b >= b); // Prints: -1 (as expected) WScript.Echo(isNaN(b)); // Prints: 0 (b evaluates to a valid number) WScript.Echo(1*b); // Prints: 0 (b evaluates to 0) WScript.Echo(a >= 0 && a <= 0); // Prints: 0 (as expected) WScript.Echo(a == 0); // Prints: 0 (as expected) WScript.Echo(b >= 0 && b <= 0); // Prints: -1 (as expected) WScript.Echo(b == 0); // Prints: 0 (!!!) |
当在算术表达式或数值比较中使用时,空值变为0—与false类似,它基本上只是一种特殊的"零"。另一方面,Undefined是一个真正的"Nothing",当您试图在数字上下文中使用它时,它会变成NaN("不是数字")。
请注意,空值和未定义值接受
You might consider undefined to represent a system-level, unexpected, or error-like absence of value and null to represent program-level, normal, or expected absence of value.
通过javascript:最终指南
未定义表示变量已声明但没有值:
1 2 3 | var var1; alert(var1); //undefined alert(typeof var1); //undefined |
空是一个分配:
1 2 3 | var var2= null; alert(var2); //null alert(typeof var2); //object |
DR
使用
使用
这是我对5个原语和对象类型的使用,这解释了它们之间的区别?用例?属于
弦
如果您知道一个变量只是一个字符串,而根据惯例,所有生命周期都可以将其初始化为
1 2 3 4 | ("") ? true : false; // false typeof""; //"string"; ("Hello World") ? true : false; // true typeof"Hello World"; //"string" |
数
如果你知道一个变量只是一个数字,而所有生命周期,按照惯例,你可以把它初始化为
1 2 3 4 | (0) ? true : false; // false typeof 0; //"number"; (16) ? true : false; // true typeof 16; //"number" |
或
1 2 3 4 | (NaN) ? true : false; // false typeof NaN; //"number"; (16) ? true : false; // true typeof 16; //"number" |
布尔
如果您知道一个变量只是一个布尔值,而根据惯例,所有生命周期都可以将其初始化为
1 2 3 4 | (false) ? true : false; // false typeof false; //"boolean"; (true) ? true : false; // true typeof true; //"boolean" |
对象
如果您知道一个变量只是一个对象,而所有生命周期,按照惯例,您可以将它初始化为
1 2 3 4 | (null) ? true : false; // false typeof null; //"object"; ({}) ? true : false; // true typeof {}; //"object" |
注:智能用法off NULL是对象的错误版本,因为对象总是
所有
如果您知道一个变量有一个混合类型(所有生命周期中的任何类型),按照约定,您可以将它初始化为
另一方面,
在javasscript中,有5种基本数据类型:string、number、boolean、null和undefined。我会用一些简单的例子来解释
假设我们有一个简单的函数
1 2 3 4 5 6 7 8 | function test(a) { if(a == null){ alert("a is null"); } else { alert("The value of a is" + a); } } |
在上面的函数中,如果(a==null)与if(!a)
现在,当我们在不传递参数a的情况下调用这个函数时
1 2 | test(); it will alert"a is null"; test(4); it will alert"The value of a is" + 4; |
也
1 2 | var a; alert(typeof a); |
这将给出未定义的;我们已经声明了一个变量,但没有为该变量指定任何值;但是如果我们写
1 2 | var a = null; alert(typeof a); will give alert as object |
所以空值是一个对象。在某种程度上,我们为"a"赋值为空
理解差异的最好方法是首先让您清楚地了解javascript的内部工作原理,并理解以下两者之间的含义差异:
1 2 3 4 5 6 7 8 9 10 | let supervisor ="None" // I have a supervisor named"None" let supervisor = null // I do NOT have a supervisor. It is a FACT that I do not. let supervisor = undefined // I may or may not have a supervisor. I either don't know // if I do or not, or I am choosing not to tell you. It is // irrelevant or none of your business. |
这三种情况的含义不同,javascript用两个不同的值来区分后两种情况:
那么,由于这种哲学基础而产生的一些特定于javascript的问题是什么呢?
没有初始值设定项的已声明变量获取值
1 2 | let supervisor; assert(supervisor === undefined); |
一个从未设置过的对象的属性计算为
1 2 | const dog = { name: 'Sparky', age: 2 }; assert(dog.breed === undefined); |
1 2 | assert(null == undefined); assert(null !== undefined); |
幸好,
如果函数到达其主体的末尾,但没有显式的返回语句,则返回
顺便说一下,javascript中还有其他形式的"虚无"(学习哲学很好…)
NaN - 使用从未声明的变量并接收
ReferenceError 。 - 使用
let 或const 在其时间死区中定义的局部变量并接收ReferenceError 。 稀疏数组中的空单元格。是的,这些甚至不是
undefined ,尽管它们比较=== 和undefined。1
2
3
4
5
6
7$ node
> const a = [1, undefined, 2]
> const b = [1, , 2]
> a
[ 1, undefined, 2 ]
> b
[ 1, <1 empty item>, 2 ]
好吧,当我们听到
1 2 | typeof null; //"object" typeof undefined; //"undefined"; |
但是如果你用下面的
1 | null==undefined; //true |
也可以将
我创建了一个快速图像,让您一目了然地看到不同之处。
Both Null and undefined in JavaScript indicate absence of value.
1
2 var a = null; //variable assigned null value
var b; // undefinedDespite the fact both exist for absence of value but: Undefined
actually means the variable is not initialized. Functions that return
nothing and function parameters for which no value is supplied,
undefined value is returned. Use strict equality operator === to
distinguish between null and undefined.
参考:http://www.thesstech.com/javascript/null-and-undefined
对于
对于
因此,对于这两种类型,标签都是其类型和值。
他们之间的区别。例如:
null 为空值undefined 是一个缺少的值
或:
undefined 还没有值null 有一个值,不再有了
实际上,
但是,
1 2 3 4 5 6 7 8 9 10 11 12 | function foo() { undefined = 2; // bad idea! } foo(); function foo() { "use strict"; undefined = 2; // TypeError! } foo(); |
空和未定义都用于表示缺少某个值。
1 | var a = null; |
a已初始化并定义。
1 2 | typeof(a) //object |
空是javascript中的对象
1 2 3 | Object.prototype.toString.call(a) // [object Object] var b; |
B未定义且未初始化
未定义的对象属性也未定义。例如,对象C上没有定义"x",如果您试图访问C.x,它将返回未定义。
通常,我们将空值赋给未定义的变量。
当typeof返回undefined时,undefined是一种类型,其中as null是初始值设定项,指示变量不指向任何对象(实际上,javascript中的所有内容都是一个对象)。
当您在javascript中声明一个变量时,它被赋予值
现在您可以显式地分配一个变量
现在假设有人正在访问Person对象的middlename变量,它的值为
空-它是一个赋值,与变量一起使用表示没有值(它是一个对象)。
未定义-它是一个变量,没有给它分配任何值,所以javascript会给它分配一个未定义的值(它是一个数据类型)。
未声明的-如果一个变量根本没有被创建,它被称为未声明的。
根据Ryan Morr关于这个问题的详细文章…
"通常,如果需要为变量或属性分配非值、将其传递给函数或从函数返回非值,则空值几乎总是最佳选择。简单地说,javascript使用未定义的,程序员应该使用空值。"
看探索永恒的无底深渊
基本上,undefined是一个全局变量,JavaScript在运行时创建它,无论空值是否意味着没有给变量赋值(实际上空值本身就是一个对象)。
让我们举个例子:
1 2 | var x; //we declared a variable x, but no value has been assigned to it. document.write(x) //let's print the variable x |
未定义,这是您将得到的输出。
现在,
1 2 3 | x=5; y=null; z=x+y; |
你将得到5作为输出。这就是未定义和空值之间的主要区别
在javascript中,所有变量都存储为键值对。每个变量都存储为变量_name:variable_value/reference。
未定义意味着变量在内存中有一个空间,但没有给它赋值。作为最佳实践,不应将此类型用作赋值。
在这种情况下,如何在代码的后面一点表示您希望一个变量没有值的时间?你可以使用这个类型空,它也是一种类型,用于定义相同的东西,缺少值,但它与未定义的不同,因为在本例中,您实际上在内存中拥有值。该值为空
两者相似,但用法和含义不同。
如果变量未初始化,那么它是未定义的。未定义不是对象。示例:var myname;console.log(typeof myname);
检查控制台登录开发工具,它将被打印为未定义。
空是一个对象。如果希望某个变量为空,则使用空。空变量存在,但值未知。应按语法将其分配给变量。空值不是自动初始化的。
示例:var myname=null;console.log(typeof myname);检查CSOLE登录开发工具,它将是一个对象。
只是添加我的视图-
只有在编译语言如C++(或IDE中标记警告)的情况下,优化编译器才可删除仅声明且从不使用任何地方的变量。它最终意味着变量不存在,因为它的内存从未被分配。
对于javascript解释器,[我猜]一个变量只有从它被赋予值的那一点开始才被视为存在。在这之前,它的类型是"未定义的",并且没有为它分配内存。所以它的类型是未定义的。
javascript中的空值是表示地址的值,但该地址尚未指向任何内容[不存在的引用]。尽管如此,它还是有价值的。
空始终是内存中存在的未知对象,而未定义则不是。