面试完前端工程师被打击,回来补一下


去XX公司面试前端,给了一套题,一看,大体上不会,跟面试官说这题对我有些难,他说这是基础,你可以走了,于是我走了。人艰不拆啊。

但是作为一个知错就改的好少年,我要发扬不懂就问,不懂就去研究的优良传统。于是今天花了些时间把我有印象的题目和我的思考写出来,按照面试官的说法是基础,但是基础是重中之重啊,希望可以对各位有些帮助,如果你们有机会去XX公司面试前端,这也算作前车之鉴了。


题目1 数组排序

给了一个数字数组,有一位的有两位的,让你按照从大到小排序

基础吧,简单吧,但我就是不会(掩面)。回来查了才知道原来数组就有sort方法。
好吧,是不是我直接把数组sort一下就可以了呢,于是我试了一下

var arr = [11,2,28,5,8,4]
arr.sort() //return [11, 2, 28, 4, 5, 8]

尼玛,为什么11跑到2前面了,难道这个函数是按字来排序的,太不智能了吧。原来不带参数的sort是按照字符编码的顺序进行排序的。那么从大到小要怎么写呢?

var arr = [11,2,28,5,8,4]
arr.sort(function(a,b){return a-b})

要这样写,为什么是这样呢?sort的参数是一个排序函数,我们可以把参数a当作数组里靠后的元素,b当作数组里靠前的元素,排序函数return的值如果是正的,才执行排序,所以最后排下来是从小到大,相反,如果return的是b-a,那么就是从大到小排序。


题目2 数组清除重复项

这是另外一道题目,数组里有重复项,要怎么清除。一查我再掩面而泣,原来js里就带了filter就可以干这活。代码如下:

myArray.filter(function(elem, pos,self){return self.indexOf(elem)== pos;})

filter是过滤的意思,filter通过一个函数的参数来选择什么项需要被filter掉,函数返回true保留,false干掉。

函数参数带三个参数,第一个elem是这一项元素,第二个pos是这一项所在的位置,第三个self指的是执行filter的数组。那么,你看,巧妙吗:self.indexOf(elem) 是指这个项目在数组中的位置,位置是第一个,也就是说同样的项目在第一位和第5位都出现了,他返回的是0,而此时pos还是4,所以通过self.indexOf(elem) == pos 能判断出这一项是不是重复出现的项,如果是(返回false),则干掉它。


题目3 闭包和++

这题我真不好意思说,丢人,我先写出来吧:

function a(x){
    return function b(y){
        return y+x++
    }
}

var a1 = a(10)
var a2 = a(20)

a1(10)
a2(10)

问后面两个值。我一看这不是考闭包吗,幸亏我有点复习,就是说x被带进去了,跟里面的匿名函数创建了一个闭包,所以一个是10,一个20。这都没问题,下面一个值++,再加上10,好嘛,++优先级显然大于+,所以10+1 = 11 再加10,一个等于21,一个等于31.

尼玛,回来一试我又傻掉了,a++虽然优先级算,但是他返回的还是本身啊,++a才返回加过以后的值啊。理解的太不深刻了,该打。


题目4 说一个list里面有几个元素,让你写一段代码在点击这个元素的时候返回他在list里的index

好吧,我本来还想说终于有一道可以做的题了,但后面大字写的请使用原生javascript实现让我蒙了,完蛋,一道都做不对。

我先是在sf里提问:

这里

然后结合朋友们的答案,自己试着写,我开始是这么写的:

var nodeList = document.getElementsByTagName('li');

for(var i = 0;i < nodeList.length;i++){
   nodeList[i].onclick = function(){
        console.log(nodeList.indexOf(nodeList[i]));
   }
}

我的思路是把所有的li放到一个数组里,然后遍历他,为每个元素添加事件,事件触发数组中当前项所在的index。

但是现实无情的打击了我,报错,nodeList找不到indexOf方法,我幻想中的nodeList难道不是数组吗。依然google,才知道怪不得那么多人使用那种复杂的方式声明数组啊,方法如下:

var nodeList = Array.prototype.slice.call(document.getElementsByTagName('li'),0) ;

调用array对象的方法slice,把取得的li放进去,这样能保证这玩意是一个数组,具有数组的一切方法。

然后我继续执行,擦,不对循环里的i永远是最后一项的值,不对,这不就是闭包里说的要避免的情况吗?也就是说onclick的匿名函数和变量i之间建立起了一个闭包,而这个i是循环以后最后的那个值。

然后呢,上网搜解决办法呗。原来解决循环闭包错误的办法就是再创建一个闭包函数,结果这个函数只需要打印出循环中的i就行了,最终代码如下:

var nodeList = Array.prototype.slice.call(document.getElementsByTagName('li'),0) ;

function conIndex(i){
    return function(){
          console.log(i)
    }
}   

for(var i = 0;i < nodeList.length;i++){
    nodeList[i].onclick = conIndex(i);
}

我没有较系统的学习计算机知识,我这个人学习还有一个特点特别不喜欢用术语,从高中开始我就喜欢把知识用我理解的方式讲出来,虽然一直在做前端,但是越来越发现自己的知识不够用,对js的理解还不够深入。我想嘛,js知识就那么多,它增长的速度只要赶不上我学习的速度,就总有一天我能把它全学会,我的目标是,下一次去面试的时候可以理直气壮的把他们给的基础题目完全搞定!


2 responses on “面试完前端工程师被打击,回来补一下

naive进行回复 取消回复

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>