共5024字,6分钟后,2分钟阅读,本文从已知的每周专栏栏目开始,写在前台,我做了2多年面试官,采访了数百位前端工程师。我很惊讶地发现,超过80%的考生没有回答以下问题。在地球,这个惊人的面试问题是什么他对候选人有什么样的能力你读这篇文章的灵感是什么慢慢听我说

不起眼的开始

招聘前端工程师,尤其是高级和高级前端工程师,是坚实的JS基础的必要条件。不太扎实的工程师在面对前端开发的各种问题时会束手无策,当我查看应聘者的JS基础时,我经常提供以下代码,然后让应聘者分析它实际运行的结果:


对于(var i = 0;i < 5;i + +){
setTimeout(){()函数(
console.log(新的日期,我);
},1000);
}

console.log(新的日期,我);




这段代码很短,只有7行,我想在这里读的学生不需要我解释代码在做什么。当考生面对这段代码时,结果不一样,下面是一个典型的答案:

A. 20%将快速扫描的代码,然后把结果:0,1,2,3,4,5;

B. 30%人看一行行代码,然后把结果:5,0,1,2,3,4;

C. 50%将代码仔细,然后把结果:5,5,5,5,5,5;



只要正确理解js中同步和异步代码之间的差异、变量的范围和闭包,您就会知道正确的答案是C,而代码的实际输出是:


2017-03-18t00:43: 45.873z 5
2017-03-18t00:43: 46.866z 5
2017-03-18t00:43: 46.868z 5
2017-03-18t00:43: 46.868z 5
2017-03-18t00:43: 46.868z 5
2017-03-18t00:43: 46.868z 5


接下来我会问:如果我们同意用箭头表示前后两个输出之间有一秒钟的间隔,那么逗号前后的两个输出之间的时间间隔可以被忽略,那么如何描述代码的实际操作结果呢下面有两个答案:

60%人将被描述为:5 - > 5 - > 5 - > 5 - > 5, 5,每个人之间有第二时间间隔;

B. 40%人将被描述为:5 - > 5,5,5,5,5第一,5秒后直接输出,5个输出5;



这就要求考生熟悉js中的定时器机制,执行循环,几乎同时设置5个定时器,在正常情况下,定时器将在第二个触发器中触发,并且循环的输出端立即执行,显然,正确的描述是B.。

如果是通过这里,100人中只有20人能通过面试,这里的学生可以仔细思考。你考试及格了吗

问题1:关闭

如果这个问题只是js异步代码,考生理解变量的作用域,限制太大,然后我会问,如果所需的代码输出为:5 -> 0,1,2,3,4。如何转换代码熟悉闭包的学生很快就能给出以下解决方案:


对于(var i = 0;i < 5;i + +){
(函数)
setTimeout(){()函数(
console.log(新日期,J);
},1000);
})(一);
}

console.log(新的日期,我);




生活(立即调用函数巧妙利用表达式语句执行的函数表达式)来解决因关闭而导致的问题,这是一个好主意,但是初学者可能不认为这个代码是很好的,至少在早期进入这个想了一会儿才真正理解。

有没有更直观的方法答案是肯定的,我们只需要在循环体上做一点操作,这样负责输出的代码就可以得到每个周期的i值,我应该怎么做呢在js中使用基本类型(原始类型)的参数传递是值传递(通过值)的特性,转换下面的代码并不困难:


var输出=函数(i){
setTimeout(){()函数(
console.log(新的日期,我);
},1000);
};

对于(var i = 0;i < 5;i + +){
输出(i);这个过去的i值被复制。
}

console.log(新的日期,我);




能够给出这2个解决方案的候选人可以考虑对JS基础和10个点的良好理解和使用。当然,在实际面试中,候选人给出以下代码:


对于(让i = 0;i < 5;i + +){
setTimeout(){()函数(
console.log(新的日期,我);
},1000);
}

console.log(新的日期,我);




细心的同学会发现,只有很轻微的变化,即6块级的使用范围(块范围)让代替VaR,但代码在实际运行时错误的,因为最终的输出使用我不在其范围内存在,我只存在于循环内。

谁能想到ES6特性的学生是不对的,但他们了解ES6,可以加5分,继续关注以下问题。

问2:ES6

一些有经验的前端学生可能不耐烦地在这里阅读。他所知道的大部分都是他所知道的。先别担心,挑战的难度会继续增加。

接着上面的继续问:如果所需的代码输出到0 > 1 > 2 > 3 > 4 > 5,并在原有的循环代码块和两console.log不变的情况下,如何将代码可新需求的准确描述:代码0的输出后立即执行,在1、2、3、4输出的每一秒,在第五秒5的输出周期的结束时间(这可能是为了避免学生卡住了,因为在JS触发计时器可能是不确定的,具体看看Javascript定时器工作)。

看到这里,有些同学会给出以下可行的解决方案:


对于(var i = 0;i < 5;i + +){
函数(j){
setTimeout(){()函数(
console.log(新日期,J);
},1000 *);修改这里的0~4定时器时间。
})(一);
}

setTimeout()函数({ / /这增加计时器超时设置为5秒
console.log(新的日期,我);
},1000×i);




必须承认,这种方法虽然粗糙而有效,但并不是额外的好处。如果我们想将这个需求抽象如下:在完成一系列异步操作(每个周期有1个异步操作)之后,然后做其他事情,我们如何组织代码你认为这个聪明的人怎么样是的,这是承诺。

也许有些学生会问,这难道不是控制台上的几个数字吗至于这矫枉过正你知道,面试官真的想看看应聘者是否有一定的能力和素质,因为在现代前端开发中,异步代码无处不在。熟悉和掌握异步操作过程控制是合格开发人员的基本技能。

一路上,不难给出一个基于承诺的解决方案。(因为承诺是6,新的特征是它更好地为我们的新代码写6如果你这样做,可能会让面试官介意):


常量任务{ };
对于(var i = 0;i < 5;+ +);此处的语句不能更改为允许,如果您想这样做
(j)= {
Tasks.push(新(承诺(解决)= > {
(setTimeout()= > {
console.log(新日期,J);
解析(解析);这里必须是,否则代码将不按照预期的工作。
},1000 *);计时器超时逐渐增加
});
})(一);
}

promise.all(任务)(,)(= > {
(setTimeout()= > {
console.log(新的日期,我);
},1000);这里只需要将超时设置为秒。
});




相反,作者更喜欢下面的代码,看起来更简洁。我们应该知道编程风格也是许多面试官的重点。当代码被读取时,粒度越小,模块化越好,这无疑是个加分点。


常量任务};此存储的异步操作承诺
常量输出
(setTimeout()= > {
console.log(新的日期,我);
决心();
},1000×i);
});

生成所有的异步操作
对于(var i = 0;i < 5;i + +){
Tasks.push(输出(I));
}

在异步操作完成后,我的最终输出
promise.all(任务)(,)(= > {
(setTimeout()= > {
console.log(新的日期,我);
},1000);
});




在这里读学生,祝贺你,你在下次面试中也有类似的问题,至少80分。

我们都知道,保证代码的使用比异步回调机制使代码更具可读性,但很明显,与承诺的问题,如果不答应拒绝,可能导致错误的丢进黑洞,但新版本的Chrome和节点7。x未处理排斥预警可以给异常处理,和这些错误的调查还需要一些特殊的技巧(浏览器、节点。JS)。

Ask 3:ES7

既然你已经在这里看到,然后坚持2分钟,下一个内容将使你明白你的坚持是值得的。

在决定聘用的另一个重要的能力,大多数面试官是前一个候选人的要求,即技术驱动,简单的说就是候选人喜欢内部电机驱动他在美丽的方式解决工程问题,继续按照业务和技术越来越Niubi,什么是Niubi建议阅读此程序的生命分析。

话说回来,既然答应了,你如何使用异步等待功能在ES7使代码更简洁你能根据你现在掌握的知识给出答案吗请在这里停1分钟,好好想想。

下面是作者给出的参考代码:


模拟其他语言的睡眠,实际上是任何异步操作。
const的睡眠(timeountms)=承诺(新= > = > {(解决)
setTimeout(解决,timeountms);
});

((异步)= > { / /语句执行异步函数表达式
对于(var i = 0;i < 5;i + +){
等待睡眠(1000);
console.log(新的日期,我);
}

等待睡眠(1000);
console.log(新的日期,我);
});




总结

谢谢您抽出时间来这里阅读。我相信你所得到的不仅仅是用JS精确控制代码输出的技巧,而且是前端工程师成长的基础:坚实的语言基础,与时俱进和强大的技术驱动力。

以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。