一道挖坑面试题
突然想到了一个给面试者挖坑的面试题:
以下代码的运行结果是:
(undefined = 42) && console.log(undefined)
1) 报错
2) 无输出
3) 输出 42
4) 输出 undefined
解释这题之前,先来介绍下怎么想到它的。
void 0
这一切起源于,void 0。
如果我们观察ts、bable的转换结果或者一些js库,我们会发现在需要使用undefined的部分大都使用了void 0。
直到昨天,我才去了解了下void 0是个啥,然后发现真有意思。
首先,void 0结果就是undefined,但是代码长度上稍短一些。然后呢,undefined在js里并不是关键字之类的,它只是window上的一个属性。
void有两种形式,一个是空格加参数,一个就是括号,它接收一个参数,但不管这个参数是啥,都返回undefined:
void 0
void 42
void 'hello world'
void void 0
void(void(0))
是的,以上都是undefined。
undefined
然后呢,如刚才说的,undefined不是关键词,它是window上的一个属性,所以一下代码都可以运行:
undefined = 42;
window.undefined = 42;
var undefined = 42; // let和const则不行,因为undefined已经存在了
以上代码虽然都不会报错,但是我们会发现undefined还是undefined。
原因也很简单:
Object.getOwnPropertyDescriptor(window, 'undefined');
// {value: undefined, writable: false, enumerable: false, configurable: false}
没错,这玩意儿是不可写的。
void 0的用途
但是呢,既然它不是关键子,那挡不住声明个变量叫这名字啊:
(function() {
const undefined = 42;
console.log(undefined); // 42
})();
其实不少js库都有这样的代码:
(function(self, undefined) {
...
})(window);
这里直接把undefined搞成了局部变量,这样用它时就不是从window上去取了。
所以呢,为了有闭包把undefined给改了,还是使用void 0方便些。
除此之外,void还可以给iife使用:
void function() {
console.log(42);
}();
面试题解答
最后解答一下开头说到的面试题。
首先,它不会报错。
然后呢,赋值表达式的值是右值,所以虽然undefined的值不会被改掉,但console.log是会执行的。
所以答案就是输出undefined啦。
最后,感谢大家浪费时间学习这些并不是太有用的知识。