目录
起因
闲来无事,在学习 JavaScript,碰巧看到关于 void
的相关知识点,想到以前也没有仔细看过 void
的具体含义,因此便找来一些文章来看。
然后,就看到了一些提问,在讨论 return void(0);
与 return;
的区别,但是网上的一些答案都不太明显,因此便起了记录一下的想法。
当然,也有可能是有大佬们写的非常详尽的文章的,但是我也懒得找了;毕竟学习的过程中,自己写一遍甚至要比看别人的文章十几遍都要印象深刻一些。
顺便提一下,事实上,是有一篇讲【为什么用「void 0」代替「undefined」】的文章写的挺好的,可以去看一下,看完后甚至都不用看我这篇文章,对 return void(0);
与 return;
的区别也能有一个非常清楚的认识。
「return;」 = 「return undefined;」
先来看 MDN 对 return 的解释:
也就是说,return;
= return undefined;
非全局作用域中undefined可以被用作变量名
从 MDN 的权威文档中我们可以得知,undefined
是全局对象(window)的一个属性,而不是一个保留字(关键字)。
因此,在 ES5 之前的一些低版本 IE 中 undefined
是可以被重写的。
var undefined = 10;
// undefined -- chrome
// 10 -- IE 8
alert(undefined);
而在 ES5 之后,对 undefined
做了一些改动,将其变为了一个不可配置(non-configurable)、不可重写(non-writable),不可枚举(non-enumerable) 的属性。
// undefined
alert(undefined);
undefined = 10;
// undefined
alert(undefined);
但是,非常不幸的是,由于 “undefined” 不是 JavaScript 中的一个保留字(关键字);因此,在非全局作用域中,“undefined” 可以被用做一个变量名。
(() => {
const undefined = 10;
// 10
alert(undefined);
})();
当然,非全局作用域中,如果并没有定义一个名叫 “undefined” 的变量,那么,undefined
的值还是 undefined
。
(() => {
// undefined
alert(undefined);
})();
并且,在全局作用域下,如果你想要定义一个名叫 “undefined” 的变量,那么,恭喜你,你将得到一个ERROR。
因此,最好不要使用「return undefined;」
如果真的习惯了 return undefined;
这种写法,然后又凑巧有人在局部作用域中搞了个 undefined
变量,那估计能把人逼疯!😂
「undefined」=「void 0」=「void(0)」
先来看 MDN 对 void 的解释:
也就是说,undefined
= void 0
= void(0)
。
换言之,return;
= return void 0;
= return void(0);
。
因此,「return;」=「return void 0;」=「return void(0);」
function test1() { return undefined;}
function test2() { return void 0; }
function test3() { return void(0); }
test1(); // undefined
test2(); // undefined
test3(); // undefined
使用哪种写法,纯看喜好
补充:「void(0)」与「void 0」的区别,其中的括号是什么意思
从以上的图片中可以看到,void expression
中的 expression
事实上会产生副作用。
那么,什么意思呢?
> let a = 2; // 假设有一个变量 a 为 2
> void a = a + 2; // 让其产生副作用,猜测返回 undefined,但 a 的值会变成 4
// 但事实上,会报错
Uncaught SyntaxError: Invalid left-hand side in assignment
> void (a = a + 2); // 加上括号,这下不报错了
undefined
> a // 在副作用下,a 的值也改变了
4
> void(a = a + 2); // 那么,如果我把 void 与括号之间的空格去掉呢
undefined
> a
6
也就是说,void 0
= void (0)
= void(0)
= void (0)
。
即,void(0)
中的括号只是为了预防副作用表达式报错而加的一个保护。