[关闭]
@yacent 2016-10-24T23:21:50.000000Z 字数 4383 阅读 851

美团 一面

面试题目


好吧,美团的面试,还是第一次尝试,也没有什么人有经验,本来约好的上周四给我的电面,后来发现根本没有来电话,害我紧张了一个下午,今天,也就是周一,面试官发来短信致歉,说上周太忙了,忘记了这件事情,问我下午有没有空,随即也就答应了面试。

首先是问了一下instanceof 的相关题目

var a = new A();

问 :a instanceof A 是否一定会返回true

false,这题应该很简单的,不一定都会属于A,只要A函数对象的话,a instanceof A就会返回false。具体看如下的代码。

  1. function A() {
  2. return function B() {};
  3. }
  4. var a = new A();
  5. console.log(a instanceof A); // false

从上面就可以看到,a instanceof A不一定都是正确,关于instanceof的使用及原理,我觉得可以看看 http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/,这篇blog,关键是要看构造函数的prototype和实例的[[prototype]]是不是一致的,其实大部分时候只需要理解下图的内容就可以了。
JavaScript原型链图


接下来是关于this上下文环境的判断

var foo = {
    bar : function() {
        console.log(this);
    }
}

问:this指向的是谁

foo.bar(); // foo
var func = foo.bar;
func(); // window

这类题目的话,可以去看看博客或者说是书本,应该由很多这方面的相关知识。


模块化

你有了解过模块化吗?因为我没有很系统的用过,只能弱弱地说一句,了解过,然后面试官问我,那你说说吧,我就记得我当时说了"大概理解是根据功能或者说根据数据结构等方式对其进行分模块,表现就表现在js文件的分块上,然后实现模块的方式主要有CMD和AMD两种方式,然后又大概说了一下……" 感觉答得很烂,不知道自己在说啥,还需要进行资料的查阅。

ES6

问:你对ES6有没有哪方面的

这个因为我真的没有很仔细的去了解过,所以只是答了一点点毛皮,一时间也看不过来,就只是回答了 let const for or generator,然后这个话题又草草结束了

关于es6的相关知识,http://es6.ruanyifeng.com/ 可以看看


HTTP

问:


Ajax
问:
请你说说js当中ajax是如何实现的?即创建ajax的过程

1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
3)设置响应HTTP请求状态变化的函数.
4)发送HTTP请求.
5)获取异步调用返回的数据.
6)使用JavaScript和DOM实现局部刷新.

事件机制

问:
知道事件机制吧?

分为 捕获阶段、目标阶段和冒泡阶段

为什么需要分为 捕获阶段 和冒泡阶段?

这个当时没有怎么答出来,因为是真不是很清楚,为什么要进行这两种机制的分类,面试完之后去查阅了一下资料,我也不能说出个所以然,只能暂且地认为是 **历史遗留问题**,即网景公司和微软分别提出了 捕获机制 和 冒泡机制。我也只能暂时想到这方面。

请你说一说事件委托。

这个我给他举了一个例子,即比如一个ul元素下,有许多个li元素,我们需要输出li中的文本,原本平常的做法就是给每一个li都添加一个事件绑定,但是我们可以通过事件委托的机制,利用冒泡机制,来实现只绑定一个事件处理函数也可以完成上面所说的功能
  1. ////////// html ///////
  2. <ul id="#ulist">
  3. <li>1</li>
  4. <li>2</li>
  5. <li>3</li>
  6. <li>4</li>
  7. <li>5</li>
  8. </ul>
  9. ///////// javascript //////////
  10. var ulist = document.getElementById("ulist");
  11. ulist.addEventListener('click', function(event) {
  12. var that = event.target;
  13. console.log(that.innerHTML);
  14. }, false)

如果ul当中的元素不是全都是li呢,比如有a之类的,但是我只要li触发事件,你怎么做。

好吧,当时我对这题是有点懵逼,因为一下子想不起来如何去获得元素的名字,只是告诉了面试官,获取元素名字然后再进行判断就好。后来回来查阅了一下DOM的相关操作,其中在Node类型当中,可以获取节点的元素名。修改的代码如下
  1. ///////// javascript //////////
  2. var ulist = document.getElementById("ulist");
  3. ulist.addEventListener('click', function(event) {
  4. var that = event.target;
  5. if (that.nodeName.toLowerCase() === 'li') {
  6. console.log(that.innerHTML);
  7. }
  8. }, false)
总结一下,事件委托的好处主要是 
1. 能减少事件绑定的次数,日后需要修改该事件代理的时候,不必要每一个子元素都进行修改,只需要修改事件委托就好了。 
2. 就是节省内存消耗,提升性能。
3. 动态变化的DOM结构时,仍然可以监听。

那知道有什么事件是一定要在捕获阶段进行监听的吗?

这题当时没有怎么答上,因为不是非常清楚。没有想到什么必须是在捕获阶段就进行监听。后来查阅了一下资料,我认为的答案应该是说比如在三个嵌套的div当中,每个div都绑定了click事件,但是当我们需要实现点击最内层的div时,只触发该div所绑定事件,而其余div的事件不触发时,我们就必须只监听捕获,而不监听冒泡。

所有事件都会冒泡吗?如果没有,举些例子。

我当时说了不是,然后说了mouseenter和mouseleave不会进行冒泡,blur也不会进行冒泡

正则表达式

问:
写一个正则表达式,使的类似字符串 -webkit-box-shadow转换为驼峰形式 webkitBoxShadow

先说说这题,用正则表达式的话,大家应该先想想怎么样替代,然后就是要注意将-替换掉,但是第一个-后面的字母不能转换为大写,这是我一开始忽略的问题,所以写的有点点错,下面给了一个写错的和修正后的版本。
  1. /* 错误版本 */
  2. var str = "-webkit-box-shadow";
  3. var reg = /-(\w)/gi;
  4. function replaceH(str) {
  5. return str.replace(reg, function($0, $1) {
  6. return $1.toUpperCase();
  7. });
  8. }
  9. /* 修正版本 */
  10. var reg = /(\w?)(-)(\w)/gi;
  11. function replaceH(str) {
  12. return str.replace(reg, function(a, b, c, d) {
  13. if (b == '') {
  14. return d;
  15. } else {
  16. return c + d.toUpperCase();
  17. }
  18. });
  19. }

数组去重

好吧,这应该算是一个经典的问题了吧,我先写了一种,但是后来又改了需求,就又改了一种垃圾的算法。下面分享一下

  1. function unique(arr) {
  2. var res = [];
  3. for (var i = 0, len = arr.length; i < len; i++) {
  4. if (!res[arr[i]]) {
  5. res[arr[i]] = arr[i];
  6. }
  7. }
  8. return res;
  9. }
但是这种方式,细看就会发现错误了,因为没有的地方会是undefined,应该不符合去重的要求,下面是后来写的几种去重的方式。
  1. /*method 1*/
  2. function unique(arr) {
  3. var n = [];
  4. for (var i = 0, len = arr.length; i < len; i++) {
  5. if (n.indexOf(arr[i]) == -1) {
  6. n.push(arr[i]);
  7. }
  8. }
  9. return n;
  10. }
  11. /* method 2 使用hash表来记录*/
  12. function unique(arr) {
  13. var n = [];
  14. var hash = {};
  15. for (var i = 0, len = arr.length; i < len; i++) {
  16. if (!hash[arr[i]]) {
  17. hash[arr[i]] = true;
  18. n.push(arr[i]);
  19. }
  20. }
  21. return n;
  22. }
  23. /*method 3 也是使用 indexOf来进行实现*/
  24. function unique(arr) {
  25. var n = [];
  26. for (var i = 0, len = arr.length; i < len; i++) {
  27. // 若当前数组的第i项在当前数组中第一次出现的位置不是i,则为重复,否则存入
  28. if (arr.indexOf(arr[i]) == i) {
  29. n.push(arr[i]);
  30. }
  31. }
  32. return n;
  33. }
  34. /*method 4使用排序后*/
  35. function unique(arr) {
  36. arr.sort();
  37. var n = [arr[0]];
  38. for (var i = 0, len = arr.length; i < len; i++) {
  39. if (arr[i] !== n[n.length - 1]) {
  40. n.push(arr[i]);
  41. }
  42. }
  43. return n;
  44. }
个人比较喜欢第二种方法,用hash表来记录,效率高而且简单。第四种其实也还不错,但是缺点就是会改变原来的数组的顺序,如果题目要求顺序不改变的话,这样就不能了。第一和第三种方法主要是使用indexOf的方法,效率低,因为其会遍历数组,每次都会,效率低。当然如果想要效率更低的话,用两个循环来进行比较,不推荐。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注