若是您符合高级开发人员的资格,其工做涉及JavaScript,那么在编码面试中颇有可能会被问到棘手的问题。javascript
遵循这个建议:“熟能生巧”。深刻有规律地学习JavaScript将提升您的编码能力,而且能够提升您的面试技巧。java
在这篇文章中,你会发现7个乍一看很简单但很棘手的JavaScript面试问题。面试
虽然一开始这些问题看起来是随意的,可是它们试图与JavaScript的重要概念挂钩。因此你最好在下次面试前练习一下!数组
如下代码段中用于运算 typeof a
和 typeof b
的内容:浏览器
function foo() { let a = b = 0; a++; return a; } foo(); typeof a; // => ??? typeof b; // => ???
让咱们看一下第2行:let a = b = 0
,该语句声明一个局部变量a,然儿,它也声明了全局变量b。闭包
在 foo()
范围或全局范围中都没有声明变量b。所以JavaScript将 b = 0
表达式解释为 window.b = 0
。换句话说,b是意外建立的全局变量。ide
在浏览器中,以上代码片断等效于:函数
function foo() { let a; window.b = 0; a = window.b; a++; return a; } foo(); typeof a; // => 'undefined' typeof window.b; // => 'number'
typeof a
等于 'undefined'
,变量 a
存在于 foo()
范围内,而在外部范围内不使用。学习
由于b是一个值为0的全局变量,因此b的类型的值为 'number'
。测试
clothes[0]
的值是什么?
const clothes = ['jacket', 't-shirt']; clothes.length = 0; clothes[0]; // => ???
数组对象的 length
属性具备特殊的行为:减小length属性的值的反作用是删除本身的数组元素。所以,当JavaScript执行 clothes.length = 0
的时候将删除全部元素。
clothes [0]
等于 undefined
的,由于 clothes
数组已被清空。
numbers
数组的内容是什么?
const length = 4; const numbers = []; for (var i = 0; i < length; i++);{ numbers.push(i + 1); } numbers; // => ???
让咱们仔细看一下分号 ;
出如今左大括号 {
:
这个分号很容易被忽略,它建立了一个空语句。空语句是不作任何事情的空语句。
for()
在空语句上进行4次迭代(不执行任何操做),而忽略实际将项目推入数组的块:{number.push(i + 1);}
。上面的代码等效于如下代码:
const length = 4; const numbers = []; var i; for (i = 0; i < length; i++) { // does nothing } { // a simple block numbers.push(i + 1); } numbers; // => [5]
for()
将 i
变量递增到4,而后JavaScript一次进入块 {number.push(i + 1);}
,将 4 +1
推入数字数组。
所以,numbers
数组的内容为 [5]
。
arrayFromValue()
返回什么值?
function arrayFromValue(item) { return [item]; } arrayFromValue(10); // => ???
很容易错过 return
关键字和 [item]
表达式之间的换行符。此换行符使JavaScript自动在 return
和 [item]
表达式之间插入分号。
这是等效的代码,在返回后插入了分号:
function arrayFromValue(item) { return; [item]; } arrayFromValue(10); // => undefined
return;
函数内部使其返回 undefined
。所以 arrayFromValue(10)
的值为 undefined
。
如下代码将输出什么到控制台?
let i; for (i = 0; i < 3; i++) { const log = () => { console.log(i); } setTimeout(log, 100); }
若是您之前从未据说过这个棘手的问题,则极可能您的答案是 0
、1
和 2
:这是错误的。当我第一次尝试解决它时,这也是个人答案!
执行此代码段有两个阶段。
for()
重复3次,在每次迭代过程当中,都会建立一个新的函数 log()
来捕获变量 i
。而后 setTimout()
计划执行log()
。for()
循环完成时,i
变量的值为 3
。log()
是一个捕获变量 i
的闭包,该变量在 for()
循环的外部范围中定义。请务必注意,闭包能够词法捕获 i
变量。
第二阶段发生在100ms以后:setTimeout()
调用了3次计划的 log()
。log()
读取变量i的当前值为3,并记录到控制台3。这就是为何控制台输出为3
、3
和 3
的缘由。
若是您难以理解闭包,建议阅读 “ JavaScript闭包的简单说明”。
您知道如何将代码段记录为0、1和2吗?请在下面的评论中写下您的解决方案!
这个等式的结果是什么?
0.1 + 0.2 === 0.3 // => ???
首先,让咱们看一下 0.1 + 0.2
的值:
0.1 + 0.2; // => 0.30000000000000004
0.1
和 0.2
的总和不彻底是 0.3
,而是略高于 0.3
。
因为以二进制方式对浮点数进行编码,所以像浮点数相加之类的操做会产生舍入偏差。
简而言之,直接比较浮点数并不精确。
所以 0.1 + 0.2 === 0.3
的结果是 false
。
点击 0.30000000000000004.com 了解更多信息。
若是在声明前访问 myVar
和 myConst
,会发生什么状况?
myVar; // => ??? myConst; // => ??? var myVar = 'value'; const myConst = 3.14;
提高和临时死区是影响JavaScript变量生命周期的两个重要概念。
在声明以前访问 myVar
的结果为 undefined
。在初始化以前,提高的 var 变量具备 undefined
的值。
然儿,在声明行以前访问 myConst
会引起 ReferenceError
。const
变量处于临时死区,直到声明行 const myConst = 3.14
。
您能够认为某些问题对面试毫无用处。我有一样的感受,特别是关于鹰眼测试。尽管如此,他们可能会被问到。
不管如何,其中许多问题均可以真正评估您是否精通JavaScript,例如棘手的闭包。若是您在阅读帖子时遇到一些困难,这很好地代表了您接下来必须学习什么!
在面试中提出棘手的问题是否公平?让我知道你的意见。
原文:https://dmitripavlutin.com/simple-but-tricky-javascript-interview-questions/
做者:Dmitri Pavlutin
翻译:作工程师不作码农