理想情况下,应聘者应该有一份比较完整的GitHub“简历”,这样面试官可以一起来回顾你参与的开源项目。他们通常会先浏览你的代码,然后针对某一个具体的代码设计问你一些问题。如果应聘者在这一部分表现非常,就可以直接进入团队社交能力的考察部分。否则的话面试官可能会让你做一些编程题目。
大多数面试管是非常注重实践的,整个面试过程几乎全都是在写代码。他们不会问一些比较抽象的或者算法相关的问题。一些问题看起来比较简单,但实际上每一类问题都可以让面试官洞悉应聘者在JavaScript的某一方面的知识。
部分:对象原型
我们先从简单的来。实现一个spacify函数:接受一个字符串作为参数,然后把这个字符串的每个字符都用空格隔开后返回。例如:
JavaScript
1spacify(‘hello world’) // =》 ‘h e l l o w o r l d’
虽然这个问题看起来非常容易,但结果却证明从这个问题问起是很合适的,尤其是对于一些电话面试者,他们声称了解JavaScript,却连一个完整的函数都不会写。下面是这个题目的正确答案,有的应聘者通过循环来实现也是可以的。
JavaScript
1
2
3function spacify(str) {
return str.split(‘’).join(‘ ’);
}
接下来这个问题是让应聘者直接为String对象增加spacify的函数,像这样:
JavaScript
1‘hello world’.spacify();
通过这个问题我可以了解到应聘者对于函数原型基础知识的掌握情况。另外这个问题经常会引发另外一个有趣的讨论:直接在prototypes上尤其是在Object的prototypes上定义属性的风险。
终的答案类似下面的代码:
JavaScript
1
2
3String.prototype.spacify = function(){
return this.split(‘’).join(‘ ’);
};
这时候面试官还会让应聘者解释函数表达式(expression)和函数声明(declaration)的区别。
第二部分:参数
接下来会问一些简单的问题,这些问题可以帮面试官了解到应聘者对参数对象的理解程度。
首先,调用一个尚未定义的log函数:
JavaScript
1log(‘hello world’)
然后让应聘者去实现log函数:接受一个string参数然后直接传给console.log(),正确答案就在下面,但有些比较的应聘者会直接使用apply函数来实现。
JavaScript
1
2
3function log(msg){
console.log(msg);
}
完成上一步后我会修改调用log的方式:传递多个参数。告诉应聘者面试官希望log函数不止接收一个数字作为参数,它应该可以接受任意个数字作为参数。同时也提醒应聘者cosole.log()本身就可以接收多个参数。
JavaScript
1log(‘hello’, ‘world’);
理想情况下应聘者应当直接使用apply来实现这个功能。但有时你会混淆apply和call的二者的区别,这时你可以给他们一些提示。另外将console作为上下文参数这一点也很重要。
JavaScript
1
2
3function log(){
console.log.apply(console, arguments);
};
然后可能会让要求在每一条日志消息前加上“(app)”的前缀,例如:
JavaScript
1‘(app) hello world’
现在,问题就有点棘手了。能力强些的应聘者应当知道arguments是一个伪数组,在使用它之前得先把它转换成标准数组。通常我们用Array.prototype.slice就可以实现这一点,像下面这样:
JavaScript
1
2
3
4
5function log(){
var args = Array.prototype.slice.call(arguments);
args.unshift(‘(app)’);
console.log.apply(console, args);
};
第三部分:上下文
下面的这一组面试题可以考察应聘者对于JavaScript中context和this的理解。,面试官先给出下面的定义,注意,count的属性是从当前的上下文中读取的。
JavaScript
1
2
3
4
5
6var User = {
count: 1,
getCount: function() {
return this.count;
}
};
然后会让应聘者写出下面代码的输出结果:
JavaScript
1
2
3console.log(User.getCount());
var func = User.getCount;
console.log(func());
这个题目正确的答案是1和undefined。令人吃惊的是有很多人会在这种关于上下文的基础知识上犯错。func函数被调用时,它的上下文是windows,而windows是没有count属性的。把这些都和应聘者做了解释,然后问如何才能func函数始终都能以User作为上下文被调用,这样它就能正确运行从而返回1。
正确的答案是使用Function.prototype.bind,例如:
JavaScript
1
2var func = User.getCount.bind(User);
console.log(func());
通常面试官会告诉应聘者有一些老的浏览器是不支持bind函数的,然后让你们自己来写一个函数来模拟。有一些基础差的应聘者并不认可这一点,但对面试官来讲每一个被雇佣的应聘者对apply和call都应该有比较深入的理解,这一点很重要!
JavaScript
1
2
3
4
5
6Function.prototype.bind = Function.prototype.bind || function(context){
var self = this;
return function(){
return self.apply(context, arguments);
};
}
如果应聘者像上面那样实现了bind并且还判断了当前浏览器是否已经支持bind函数,那么应聘者可以得到额外的加分。
此时,如果应聘表现的很出色,还会让他们去实现currying参数。
第四部分:Overlay库
面试的后这一部分里,会让应聘者做一些加实际的事情,通常是去实现一个‘overlay’的库。这很方式很管用,它涉及到了整个前端开发所用到的技术:HTML、CSS 和JavaScript。如果应聘者在前面几个环节表现,可能会尽早的开始这一部分的问题。
具体的实现因人而异,但是这里几个关键点需要注意!
对于overlay covers,好使用 position: fixed 而不是 position: absolute,这样即使窗口滚动的时候也可以层铺满整个窗口。如果应聘者没有注意到这一点,就去想想这两者的区别。
CSS
1
2
3
4
5
6
7
8.overlay {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: rgba(0,0,0,.8);
}
从把内容放置到层的中心位置的方式也可以为面试官提供一些信息。有些应聘者可能会使用CSS和位置,但这样的前提是内容必须是固定宽度和长度的。另外的应聘者也可能会选择用JavaScript来定位。
CSS
1
2
3
4
5
6
7
8.overlay article {
position: absolute;
left: 50%;
top: 50%;
margin: -200px 0 0 -200px;
width: 400px;
height: 400px;
}
面试官还会要求他们实现单击关闭层的功能,然后就可以顺势讨论下几种不同类型的事件传播机制。大多数应聘者会直接为层设置一个事件监听器。
JavaScript
1$(‘.overlay’).click(closeOverlay);
看着是对的,但很快你就会发现在这个层的子元素上单击也会关闭层,这明显不是他们预期的效果。解决方法是先检查事件的targets来确保不是一个传播事件,像这样:
JavaScript
1
2
3
4$(‘.overlay’).click(function(e){
if (e.target == e.currentTarget)
closeOverlay();
});
其它
其实这些问题只覆盖了前端知识的很小一部分,面试的时候你可以问很多其他方面的问题,例如性能、HTML5 APIs, AMD vs CommonJS modules、 构造函数、数据类型以及盒模型等。我经常会根据应聘者的兴趣来搭配不同类型的问题。
相关文章
了解千锋动态
关注千锋教育服务号
扫一扫快速进入
千锋移动端页面
扫码匿名提建议
直达CEO信箱