我想知道JavaScript中null和undefined之间的区别。
当前回答
当您在javascript中声明一个变量时,它被赋值为undefined。这意味着变量是未被修改的,可以在将来分配任何值。这也意味着您不知道该变量在声明时将保持的值。
现在可以显式地将变量赋值为null。这意味着变量没有任何值。例如,有些人没有中间名。因此,在这种情况下,最好将值null赋给person对象的中间名变量。
现在假设某人正在访问person对象的中间名变量,并且该变量的值未定义。他不知道开发人员是否忘记初始化这个变量,或者它是否没有任何值。如果它的值为null,那么用户可以很容易地推断middlename没有任何值,并且它不是一个未触及的变量。
其他回答
已经给出了很多“技术性”的答案,从JS仅仅是一种编程语言的有限角度来看,所有答案都是正确的。
然而,我想补充以下想法,特别是当您将TypeScript代码作为更大项目/(企业)应用程序的一部分时:
当与某种后端交谈时,您很可能会收到JSON虽然一些后端正确地避免了在JSON中使用“null”(删除那些财产),但其他后端没有这样做现在,虽然“null”可能意味着该值是故意缺失的,但更多情况下,它并没有传达这一含义。大多数数据库使用“null”只是因为它们没有“undefined”类型。但真正的含义只是“未定义”。因此,您永远无法知道“null”值是否真的意味着故意缺席。因此,“空”并不意味着故意选择“缺失值”。一般来说,这是无法决定的。因此,在语义上,“null”和“undefined”实际上是完全相同的。
因此,为了协调一致,我坚决反对使用“null”,并希望鼓励您停止在代码中使用“null“。这比你想象的要容易得多。别误会我。我不是说不处理“null”值,只是为了避免在代码中显式使用它们。换句话说:您的代码应该仍然能够处理来自应用程序外部的意外传递的“null”值,例如通过第三方库(如Angular)或第三方后端。
以下是实现这一目标的指导原则:
避免直接的未定义类型保护(例如,如果(值==未定义){…}。相反,使用间接类型保护(也称为真实性检查),例如if(value){…}每当0或空字符串有意义时,请使用像Lodash的isNil这样的显式助手方法或在比较中包含有意义的值(例如,如果(!value&&value!==0){…})考虑使用不允许使用null的lint规则
理解差异的最佳方法是首先理清JavaScript的内部工作原理,并理解以下两者之间的含义差异:
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用两个不同的值(null和undefined)来区分后两种情况。您可以自由地明确使用这些值来表达这些含义。
那么,由于这种哲学基础而产生的一些JavaScript特定问题是什么呢?
没有初始值设定项的已声明变量将获得未定义的值,因为您从未说过预期值是什么。出租监督员;断言(主管==未定义);从未设置过的对象的属性求值为undefined,因为没有人说过该属性。const dog={name:“Sparky”,年龄:2};断言(dog.bred==未定义);null和undefined彼此“相似”,因为Brendan Eich是这么说的。但它们显然彼此不相等。断言(null==未定义);断言(null!==未定义);谢天谢地,null和undefined有不同的类型。null属于null类型,undefined属于undefined类型。这在规范中,但你永远不会知道这一点,因为我不会在这里重复这种奇怪的类型。如果函数到达其主体的末尾而没有显式返回语句,则返回undefined,因为您不知道它返回了什么。
顺便说一句,JavaScript中还有其他形式的“虚无”(学习哲学很好……)
NaN公司使用从未声明的变量并接收ReferenceError在其时间死区中使用let或const定义的局部变量并接收ReferenceError稀疏数组中的空单元格。是的,虽然它们与undefined相比==,但它们甚至没有定义。$节点>常量a=[1,未定义,2]>常量b=[1,2]>一个[1,未定义,2]>b级[1,<1空项>,2]
我从这里选的
未定义的值是当变量没有已分配值。空值是表示空的、空的和空的原始值,或不存在的引用。
当您通过var声明一个变量而不给它赋值时,它将具有未定义的值。就其本身而言,如果您尝试WScript.Echo()或alert()此值,您将看不到任何内容。但是,如果您在其中附加一个空白字符串,那么它会突然出现:
var s;
WScript.Echo(s);
WScript.Echo("" + s);
您可以声明一个变量,将其设置为null,行为是相同的,只是您将看到“null”与“undefined”打印出来。这确实是一个小差异。
您甚至可以将未定义的变量与null进行比较,反之亦然,条件将为true:
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是防止基于它的错误的最佳方法。
另一个例子是使用delete运算符时,您将看到未定义的弹出窗口。我们这些来自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,这通常是我们所做的。虽然我们可以将变量设置为undefineed,但我们更喜欢null,因为这不是我们曾经做过的事情。当您调试时,这意味着任何设置为null的事情都是您自己做的,而不是JavaScript。除此之外,这两个特殊值几乎相等。
const data = { banners: null }
const { banners = [] } = data;
console.log(data) // null
const data = { banners: undefined }
const { banners = [] } = data;
console.log(data) // []
null是一个特殊的关键字,表示缺少值。
将其视为一种价值,例如:
“foo”是字符串,true为布尔值,1234是数字,null未定义。
undefined属性表示尚未为变量分配包含null的值。喜欢
var foo;
定义的空变量为null,数据类型为undefined
它们都表示一个没有值的变量的值
以及null不表示没有值的字符串-空字符串-
Like
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
BUT
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
推荐文章
- Javascript和regex:分割字符串并保留分隔符
- 如何检查DST(日光节约时间)是否有效,如果是,偏移量?
- 如何打破_。在underscore.js中的每个函数
- 如何在jQuery中获得当前日期?
- 如何创建一个日期对象从字符串在javascript
- 输入触发器按钮单击
- 获取对象的属性名
- 如何检查用户是否可以回到浏览器历史
- 相当于字符串。jQuery格式
- 如何在vue-cli项目中更改端口号
- Angular 2模板中的标签是什么意思?
- JavaScript .includes()方法的多个条件
- 窗口。亲近与自我。close不关闭Chrome中的窗口
- 同步和异步编程(在node.js中)的区别是什么?
- 在d3.js中调整窗口大小时调整svg的大小