相比之下,JavaScript有两个这样的非值:undefined
和null
。在这篇博文中,我们将研究它们有什么不同,以及如何最好地使用或避免它们。
这两种值非常相似,经常互换使用。因此,它们的区别是微妙的。
1.1 ECMAScript语言规范:undefined vs. null
ECMAScript语言规范对其描述如下。
-
undefined
是 “当一个变量没有被赋值时使用” -
null
“表示有意不存在任何对象值”
1.2 两个非值–一个无法消除的错误
在JavaScript中拥有两个非值现在被认为是一个设计错误(甚至被JavaScript的创造者Brendan Eich认为)。
那为什么不从 JavaScript 中删除其中的一个值呢?JavaScript 的一个核心原则是绝不破坏向后兼容。这个原则有很多好处。它最大的缺点是,设计上的错误无法被删除。
1.3 undefined和null的历史
在Java中(它启发了JavaScript的许多方面),初始化值取决于变量的静态类型。
-
具有对象类型的变量被初始化为
null
。 -
每个原始类型都有自己的初始化值。例如,
int
变量被初始化为0
。
在JavaScript中,每个变量都可以容纳对象值和基本类型值。因此,如果null
意味着 “不是一个对象”,那么JavaScript也需要一个初始化值,意味着 “既不是一个对象也不是一个原始值”。这个初始化值就是 undefined
。
undefined 的出现
如果一个变量myVar
还没有被初始化,它的值是undefined
。
let myVar;
assert.equal(myVar, undefined);
如果一个属性.unknownProp
丢失,访问该属性会产生undefined
的值。
const obj = {};
assert.equal(obj.unknownProp, undefined);
如果一个函数有一个没有参数的返回语句,该函数隐含地返回undefined
。
function myFunc() {
return;
}
assert.equal(myFunc(), undefined);
如果一个参数x
被省略了,语言将该参数初始化为undefined
。
function myFunc() {
return;
}
assert.equal(myFunc(), undefined);
myFunc();
通过obj?.someProp
的可选链路,如果obj未定义或为空,则返回未定义。
undefined?.someProp
undefined
null?.someProp
undefined
一个对象的原型要么是一个对象,要么在原型链的末端是null
。Object.prototype
没有原型。
Object.getPrototypeOf(Object.prototype)
null
如果我们将一个正则表达式(如/a/
)与一个字符串(如'x'
)相匹配,我们要么得到一个带有匹配数据的对象(如果匹配成功),要么得到空(如果匹配失败)。
/a/.exec(‘x’)
null
JSON数据格式不支持undefined
,只支持null
。
JSON.stringify({a: undefined, b: null})
‘{“b”:null}’
4.1 undefined 和参数默认值
在以下情况下,将使用参数默认值。
-
缺少一个参数。
-
一个参数的值是
undefined
。
例如:
function myFunc(arg=‘abc’) {
return arg;
}
assert.equal(myFunc(‘hello’), ‘hello’);
assert.equal(myFunc(), ‘abc’);
assert.equal(myFunc(undefined), ‘abc’);
undefined
也触发了参数的默认值,这说明它是一个元值。
下面的例子说明了这一点的用处。
function concat(str1=‘’, str2=‘’) {
return str1 + str2;
}
function twice(str) { // (A)
return concat(str, str);
}
在A
行,我们没有为str
指定一个参数默认值。当这个参数缺失时,我们把这个状态转发给concat()
,让它选择一个默认值。
4.2 undefined 的和解构的默认值
解构中的缺省值与参数缺省值的工作原理类似–如果一个变量在数据中没有匹配,或者它与undefined
的变量匹配,就会使用它们。
const [a=‘a’] = [];
assert.equal(a, ‘a’);
const [b=‘b’] = [undefined];
assert.equal(b, ‘b’);
const {prop: c=‘c’} = {};
assert.equal(c, ‘c’);
const {prop: d=‘d’} = {prop: undefined};
assert.equal(d, ‘d’);
4.3 undefined 和 null 以及可选链
当通过 value?.prop
进行可选的链接时
-
如果
value
是undefined
或null
,则返回undefined
。也就是说,只要value.prop
会抛出一个异常,就会发生这种情况。 -
否则,返回
value.prop
。
function getProp(value) {
// optional static property access
return value?.prop;
}
assert.equal(
getProp({prop: 123}), 123);
assert.equal(
getProp(undefined), undefined);
assert.equal(
getProp(null), undefined);
下面两个操作的效果类似。
obj?.[«expr»] // optional dynamic property access
func?.(«arg0», «arg1») // optional function or method call
4.4 undefined 和 null 和 nullish 聚结
nullish 合并算子??
如果一个值undefined
或为null
,则允许我们使用默认值:
undefined ?? ‘default value’
‘default value’
null ?? ‘default value’
‘default value’
0 ?? ‘default value’
0
123 ?? ‘default value’
123
‘’ ?? ‘default value’
‘’
‘abc’ ?? ‘default value’
‘abc’
null合并赋值操作符??=
:
function setName(obj) {
obj.name ??= ‘(Unnamed)’;
return obj;
}
assert.deepEqual(
setName({}),
{name: ‘(Unnamed)’}
);
assert.deepEqual(
setName({name: undefined}),
{name: ‘(Unnamed)’}
);
assert.deepEqual(
setName({name: null}),
{name: ‘(Unnamed)’}
);
assert.deepEqual(
setName({name: ‘Jane’}),
{name: ‘Jane’}
);
下面分享一下我们自己的代码中处理undefined
和null
的最常见方法。
5.1 undefined 或 null 都不能作为实际值使用
举例,我们可能希望一个属性file.title
永远存在,并且永远是一个字符串。有两种常见的方法来实现这一点。
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NWQY015P-1710867628978)]
[外链图片转存中…(img-6SuILd6b-1710867628979)]
[外链图片转存中…(img-zYu2LZvF-1710867628979)]
[外链图片转存中…(img-vtceT83Z-1710867628980)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-dTPQr7EW-1710867628980)]