@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。具体看如下的代码。
function A() {
return function B() {};
}
var a = new A();
console.log(a instanceof A); // false
从上面就可以看到,a instanceof A
不一定都是正确,关于instanceof的使用及原理,我觉得可以看看 http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/,这篇blog,关键是要看构造函数的prototype和实例的[[prototype]]是不是一致的,其实大部分时候只需要理解下图的内容就可以了。
接下来是关于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
问:
请说你说说常见的状态码
200 301 302 304 400 403 404 500
等等,更多的状态码可以去看看HTTP协议。Ajax
问:
请你说说js当中ajax是如何实现的?即创建ajax的过程
1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
3)设置响应HTTP请求状态变化的函数.
4)发送HTTP请求.
5)获取异步调用返回的数据.
6)使用JavaScript和DOM实现局部刷新.
事件机制
问:
知道事件机制吧?
分为 捕获阶段、目标阶段和冒泡阶段
为什么需要分为 捕获阶段 和冒泡阶段?
这个当时没有怎么答出来,因为是真不是很清楚,为什么要进行这两种机制的分类,面试完之后去查阅了一下资料,我也不能说出个所以然,只能暂且地认为是 **历史遗留问题**,即网景公司和微软分别提出了 捕获机制 和 冒泡机制。我也只能暂时想到这方面。
请你说一说事件委托。
这个我给他举了一个例子,即比如一个ul元素下,有许多个li元素,我们需要输出li中的文本,原本平常的做法就是给每一个li都添加一个事件绑定,但是我们可以通过事件委托的机制,利用冒泡机制,来实现只绑定一个事件处理函数也可以完成上面所说的功能
////////// html ///////
<ul id="#ulist">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
///////// javascript //////////
var ulist = document.getElementById("ulist");
ulist.addEventListener('click', function(event) {
var that = event.target;
console.log(that.innerHTML);
}, false)
如果ul当中的元素不是全都是li呢,比如有a之类的,但是我只要li触发事件,你怎么做。
好吧,当时我对这题是有点懵逼,因为一下子想不起来如何去获得元素的名字,只是告诉了面试官,获取元素名字然后再进行判断就好。后来回来查阅了一下DOM的相关操作,其中在Node类型当中,可以获取节点的元素名。修改的代码如下
///////// javascript //////////
var ulist = document.getElementById("ulist");
ulist.addEventListener('click', function(event) {
var that = event.target;
if (that.nodeName.toLowerCase() === 'li') {
console.log(that.innerHTML);
}
}, false)
总结一下,事件委托的好处主要是
1. 能减少事件绑定的次数,日后需要修改该事件代理的时候,不必要每一个子元素都进行修改,只需要修改事件委托就好了。
2. 就是节省内存消耗,提升性能。
3. 动态变化的DOM结构时,仍然可以监听。
那知道有什么事件是一定要在捕获阶段进行监听的吗?
这题当时没有怎么答上,因为不是非常清楚。没有想到什么必须是在捕获阶段就进行监听。后来查阅了一下资料,我认为的答案应该是说比如在三个嵌套的div当中,每个div都绑定了click事件,但是当我们需要实现点击最内层的div时,只触发该div所绑定事件,而其余div的事件不触发时,我们就必须只监听捕获,而不监听冒泡。
所有事件都会冒泡吗?如果没有,举些例子。
我当时说了不是,然后说了mouseenter和mouseleave不会进行冒泡,blur也不会进行冒泡
正则表达式
问:
写一个正则表达式,使的类似字符串 -webkit-box-shadow
转换为驼峰形式 webkitBoxShadow
先说说这题,用正则表达式的话,大家应该先想想怎么样替代,然后就是要注意将-替换掉,但是第一个-后面的字母不能转换为大写,这是我一开始忽略的问题,所以写的有点点错,下面给了一个写错的和修正后的版本。
/* 错误版本 */
var str = "-webkit-box-shadow";
var reg = /-(\w)/gi;
function replaceH(str) {
return str.replace(reg, function($0, $1) {
return $1.toUpperCase();
});
}
/* 修正版本 */
var reg = /(\w?)(-)(\w)/gi;
function replaceH(str) {
return str.replace(reg, function(a, b, c, d) {
if (b == '') {
return d;
} else {
return c + d.toUpperCase();
}
});
}
数组去重
好吧,这应该算是一个经典的问题了吧,我先写了一种,但是后来又改了需求,就又改了一种垃圾的算法。下面分享一下
function unique(arr) {
var res = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (!res[arr[i]]) {
res[arr[i]] = arr[i];
}
}
return res;
}
但是这种方式,细看就会发现错误了,因为没有的地方会是undefined,应该不符合去重的要求,下面是后来写的几种去重的方式。
/*method 1*/
function unique(arr) {
var n = [];
for (var i = 0, len = arr.length; i < len; i++) {
if (n.indexOf(arr[i]) == -1) {
n.push(arr[i]);
}
}
return n;
}
/* method 2 使用hash表来记录*/
function unique(arr) {
var n = [];
var hash = {};
for (var i = 0, len = arr.length; i < len; i++) {
if (!hash[arr[i]]) {
hash[arr[i]] = true;
n.push(arr[i]);
}
}
return n;
}
/*method 3 也是使用 indexOf来进行实现*/
function unique(arr) {
var n = [];
for (var i = 0, len = arr.length; i < len; i++) {
// 若当前数组的第i项在当前数组中第一次出现的位置不是i,则为重复,否则存入
if (arr.indexOf(arr[i]) == i) {
n.push(arr[i]);
}
}
return n;
}
/*method 4使用排序后*/
function unique(arr) {
arr.sort();
var n = [arr[0]];
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i] !== n[n.length - 1]) {
n.push(arr[i]);
}
}
return n;
}
个人比较喜欢第二种方法,用hash表来记录,效率高而且简单。第四种其实也还不错,但是缺点就是会改变原来的数组的顺序,如果题目要求顺序不改变的话,这样就不能了。第一和第三种方法主要是使用indexOf的方法,效率低,因为其会遍历数组,每次都会,效率低。当然如果想要效率更低的话,用两个循环来进行比较,不推荐。