几个让我印象深入的面试题(二)

媒介

原文地点&&我的博客
知乎&&知乎专栏
简书
河南前端交换群官网

上次写了一篇几个让我印象深入的面试题(一)没看过的同砚能够去看哦。
此次文章的题目泉源:这里有凌驾20家的前端面试题,你一定不点进来看看?
假如上面的题目在我这篇文章里没有提到的话,那就申明有些题目能够很轻易查获得或许很简单或许我才能有限不能解答出来的。假如有的题目你不会而且我又没有提的那就以为就是我才能有限不能解答出来吧。嘿嘿嘿。开个打趣,不过能够在下面留言哦!

正文

照样老例子先给题目,然后在看我的答案,有什么看法能够在留言板提。

  1. 叨教a,b,c离别输出什么?

function fun(n,o){
    console.log(o)
    return{
      fun:function(m){
         return fun(m,n);
      }
    };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
  1. 用尽能够多的要领找出数组中反复涌现过的元素

比方:[1,2,4,4,3,3,1,5,3]

输出:[1,3,4]

  1. 给定一些文档(docs)、词(words),找出词在文档中悉数存在的一切文档

var docs = [{
        id: 1,
        words: ['hello',"world"]
    },
    {
        id: 2,
        words: ['hello',"kids"]
    },
    {
        id: 3,
        words: ['zzzz',"hello"]
    },
    {
        id: 4,
        words: ['world',"kids"]
    }
 ];
findDocList(docs,['hello']) //文档1,文档2,文档3
findDocList(docs,['hello','world']) //文档1
  1. 下面代码会输出什么?

var test = (function(a){
    this.a = a;
    return function(b){
        return this.a + b;
    }
    }(function(a,b){
        return a;
    }(1,2)));
console.log(test(1));
  1. 不必轮回,建立一个长度为 100 的数组,而且每一个元素的值即是它的下标。

  2. 一个整数,它的列位数字假如是摆布对称的,则这个数字是对称数。那末请找出 1 至 10000 中一切的对称数

  3. 以下代码输出效果是什么?

var myObject = {
    foo: "bar",
    func: function(){
         var self = this;
         console.log('outer func : this.foo' + this.foo);
         console.log('outer func : self.foo' + self.foo);
         (function(){
             console.log('inner func : this.foo' + this.foo);
             console.log('inner func : self.foo' + self.foo);
         })();
    }
};
myObject.func();
  1. 请写出以下正则表达式的细致划定规矩申明
    /^(0[1-9]dd?)?[1-9]d{6}d?$/

/^(1[89]|[2-9]d|100)$/i
/^[w-]+@[a-z0-9-]+({[a-z]{2,6}}){1,2}$/i

  1. 请写出打乱数组要领

  2. 写出element.getElementsByClassName 的完成要领

  3. 请写出代码输出效果

if(!("a" in window)){
    var a = 1;
}
alert(a);
  1. 请写出代码输出效果

var handle = function(a){
    var b = 3;
    var tmp = function(a){
        b = a + b;
        return tmp;
    }
    tmp.toString = function(){
        return b;
    }
    return tmp;
}
alert(handle(4)(5)(6));
  1. javscript表达式”[]==””的值是什么,为什么?

  2. Js天生下面html,点击每一个li的时刻弹出1,2,3……
    //li onclick事宜都能弹出当前被点击的index=?

<ul id="testUrl">
    <li>index=0</li>
    <li>index=1</li>
</ul>
  1. map要领是ES5中新增的,请求为ES5以下的环境增加个map要领

答案发表

第一题

function fun(n,o){
   console.log(o)
   return{
       fun:function(m){
           return fun(m,n);
       }
   };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);

我们先来一步一步地看。起首是a=fun(0)由于只传了一个参数,console输出的是第二个参数的值,所以毫无疑问地输出undefined

然后到a.fun(1)能够看出,这句话是挪用前面fun(0)返回返来的一个对象内里的函数fun,这个fun又把fun(m,n)返回出去。这个时刻请注重:这个对象里的fun在返回之前挪用了一下fun(m,n),所以console又会被实行,能够一定,它一定不会输出传进去的1,由于1作为第一个参数传到fun(m,n)里,而console是输出第二个参数的。那末此次会输出啥呢?

好了,不给人人卖关子了,答案是0。能够有人会问了,纳尼?为毛是0,0是哪来的?

要想看邃晓我的诠释,前提是你得清晰闭包。这里用到了闭包。我们晓得,闭包有个功用就是外部作用域能经由过程闭包接见函数内部的变量。着实在运转a=fun(0)的时刻,return出来的对象里的函数fun把传进来的这个0作为第二个参数传到fun内里并返回出来这时候0获得了保留。所以当运转a.fun(1)的时刻着实输出的是之前的0。背面的那两个挪用也和这个的道理一样,末了都是输出0。

这里能够会有点绕,须要花点时候来看或许自行去调试。(我已在全力表达清晰了,假如还不懂的话就留言吧=.=)。

然后到b,假如前面搞懂了这里就不难了。fun(0)运转的时刻会return一个对象出去,背面的一串链式挪用都是在挪用前面函数返回的对象里的fun,终究致使输出是undefined 0 1 2

末了到c,假如b都搞懂了,到这里基本就没什么难度了。离别会输出undefined 0 1 1

假如还不懂的话发起单步调试一下,假如照样不懂能够在下面留言,我会尽最大才能给你诠释。

第二题

用尽能够多的要领找出数组中反复涌现过的元素
比方:[1,2,4,4,3,3,1,5,3]
输出:[1,3,4]

我的思绪是,先建立一个数组。然后将传进来的数组举行排序。然后再应用sort要领遍历数组,由于它能一次取到两个数然后ab比较假如相称而且result内里又没有反复的就把a推进去。

这是我的代码:

4.5日更新

谢谢@顽强的小瓶盖同砚指出的题目

function repeat(arr) {
    var result = [];
    arr.sort().reduce(function(a, b) {
        if(a === b && result.indexOf(a) === -1) {
            result.push(a);
        }
        return b;
    });
    return result;
}
//之前题目代码
function repeat(arr){
    var result=[];
    arr.sort().sort(function(a,b){
        if(a===b&&result.indexOf(a)===-1){
            result.push(a);
        }
    });
    return result;
}

3.23日更新

谢谢@start-wrap同砚供应的要领:

function repeat(arr){
    var result = [], map = {};
    arr.map(function(num){
    if(map[num] === 1) result.push(num);
        map[num] = (map[num] || 0) + 1;
    }); 
    return result;
}

值得一提的是map[num] = (map[num] || 0) + 1,这句代码的(map[num] || 0)假如map[num]存在,则map[num]+1反之则0+1,个人以为用得很奇妙。

谢谢@早乙女瑞穂供应的淫技能:

// es6
let array = [1, 1, 2, 3, 3, 3, 4, 4, 5];
Array.from(new Set(array.filter((x, i, self) => self.indexOf(x) !== i)));
// es5
var array = [1, 2, 4, 4, 3, 3, 1, 5, 3];
array.filter(function(x, i, self) {
    return self.indexOf(x) === i && self.lastIndexOf(x) !== i 
});

es6思绪说明注解:

array.filter((x, i, self) => self.indexOf(x) !== i)
返回一个数组,该数组由arrary中反复的元素组成(返回N-1次)

new Set( [iterable] )
返回一个鸠合(反复元素在此被兼并)

Array.from( [iterable] )
返回一个数组(将上一步的鸠合变成数组)

//es5思绪说明注解:

运用indexOflastIndexOf正向推断和反向推断这个元素是不是是统一个数(假如是统一个数,则两个要领返回的i是一样的)

第三题

给定一些文档(docs)、词(words),找出词在文档中悉数存在的一切文档

我的思绪是:把第二个参数的数组用join合成一个字符串,然后用forEach遍历,离别把文档里的words也用join合成一个字符串,应用search要领找每一个文档里的words是不是包括有arrStr

这是我的代码:

function findDocList(docs, arr) {
    let arrStr = arr.join(""),
    itemStr,
    result = [];
    docs.forEach(function(item) {
        itemStr = item.words.join("");
        if(itemStr.search(new RegExp(arrStr)) !== -1) {
        result.push("文档" + item.id);
    }
    });
    console.log(result);
}
findDocList(docs, ['hello']) //文档1,文档2,文档3
findDocList(docs, ['hello', 'world']) //文档1

第四题

下面代码会输出什么?

var test = (function(a){
        this.a = a;
        return function(b){
        return this.a + b;
        }
}(function(a,b){
        return a;
}(1,2)));
console.log(test(1));

能够看到,这里有两个自实行函数。下面这个自实行函数实行完后向上面这个自实行函数传了个1所以this.a=1,这里的this指向window。然后这个自实行函数返回个函数给test变量。下面挪用test(1),这个1传进来后相当于return 1+1所以就输出2。

第五题

不必轮回,建立一个长度为 100 的数组,而且每一个元素的值即是它的下标。

假如相识Object.keysArray.form的话,这题基本上没啥难度。
答案:

Object.keys(Array.from({length:100}))

哎!等下Array.form不是es6的吗,es5的怎样完成?
代码来了:

Object.keys(Array.apply(null,{length:100}))

假如还不懂能够参考这里的解说。

第六题

一个整数,它的列位数字假如是摆布对称的,则这个数字是对称数。那末请找出 1 至 10000 中一切的对称数

我的思绪,先将数字转为字符串,然后应用数组的map要领遍历这个字符串,将字符串悉数离开变成数组,然后挪用数组的reverse要领,再将翻转后的数组join成字符串,末了对照翻转后的字符串和翻转前的字符串是不是相称即可(要领有点愚蠢,望大神指教):

function symmetric(){
    var i=1,
    str,
    newStr,
    result=[];
    for(;i<1000;i++){
        str=""+i;
        newStr=result.map.call(str,function(item){
            return item;
        }).reverse().join("");
        if(str===newStr){
            result.push(+str);
        }
    }
    return result;
}

第七题

以下代码输出什么?

var myObject = {
    foo: "bar",
    func: function(){
    var self = this;
    console.log('outer func : this.foo' + this.foo);
    console.log('outer func : self.foo' + self.foo);
    (function(){
        console.log('inner func : this.foo' + this.foo);
        console.log('inner func : self.foo' + self.foo);
    })();
    }
};
myObject.func();

这题重要考核this指向,个人以为难度不是太大,由于this已被我完整承包啦(坏笑容)。
这题的话只需斟酌谁挪用的函数this就指向谁。
函数最先实行self=this这里的this是指向myObject的,由于myObject.func()很明显是myObject在挪用它嘛,所以头两句console输出的foo都是bar
下面是一个自实行函数,要晓得,自实行函数的this平常状况下都指向window这里也不破例,所以,第三个console输出的fooundefined由于在windowfoo没定义。第四个输出的是self.foo这个self就是上面定义的selfmyObject所以,这里的foobar

第八题

请写出以下正则表达式的细致划定规矩申明
/^(0[1-9]dd?)?[1-9]d{6}d?$/
/^(1[89]|[2-9]d|100)$/i
/^[w-]+@[a-z0-9-]+({[a-z]{2,6}}){1,2}$/i

嘿嘿,正则也算我比较特长的部份。我来一个一个诠释吧,有些正则比较难用言语表达,人人领悟领悟吧。

第一个:起首^代表的是以它背面的一堆东西为开首$代表以它前面一堆东西为末端,在这里的意义就是以(0[1-9]\d\d?)?[1-9]\d{6}\d?为开首和末端的字符串。然后到第一个括号里的意义是婚配第一个字符串为0第二个字符串为1-9第三个字符串为0-9第四个字符串无足轻重,有的话婚配1-9,然后这全部括号内里的内容无足轻重。问好背面的意义是婚配第一个字符串是1-9然后背面6个字符串婚配0-9末了一个字符串无足轻重,有的话婚配0-9。

所以整顿整顿就是:婚配以0为第一个,1-9为第二个,数字为第三个;第四个无足轻重,有的话婚配数字;然后前面这一整坨无足轻重。1-9为第五个(假如前面那一坨没有的话,则从第一个算起)然后背面6个都是数字末了一个数字无足轻重的字符串,且以它为开首和末端。

下面是例子:
022222222222 //true
002222222222 //false 由于第二个数字是1-9
02222222222 //第一个括号末了一个数字者最背面的数字省略
0222222222 //第一个括号末了一个数字者最背面的数字省略
22222222 //第一个括号里的内容悉数省略
02222222 //d{6}没有满足。

第二个:婚配以1作为第一个,8或9作为第二个又或许以2-9为第一个,数字为第二个又或许婚配100的字符串,并以他们为开首和末端,疏忽大小写。

照样例子比较直观:

18 //true 婚配前面的1[89]
23 //true 婚配[2-9]d
100 //true 婚配100
17 //false
230 //false

第三个:
婚配前面最少一个数字或字母或_或-再婚配@然后再婚配最少一个字母或数字或-然后到再婚配{字母2-6个}1-2个,的字符串,并以他们为开首和末端疏忽大小写。

这个用言语形貌太难了,是我不会措辞吗,上例子吧:

3@d{aw}{ad} //true
-@-{ddd}{fs} //true
3@3{dw}{ddd} //true
3@3{dw} //false {字母2-6个}少了一个即({[a-z]{2,6}}){1,2}背面的{1,2}没满足
@3{dw}{ddd} //false [w-]+没满足
33{dw}{ddd} //false 没@
dsa@ffff{dw}{d} //false ({[a-z]{2,6}})不相符

第九题

请写出打乱数组要领

4.5日更新

参考这里

// 之前的题目代码
function randomsort(a, b) {
    return Math.random()>.5 ? -1 : 1;
    //用Math.random()函数天生0~1之间的随机数与0.5比较,返回-1或1
}
var arr = [1, 2, 3, 4, 5];
arr.sort(randomsort);

第十题

写出element.getElementsByClassName 的完成要领
我的思绪:先猎取页面下的一切元素,然后用split将传进来的多个class支解成数组,然后利两层轮回找出相符前提的元素(个人以为这类要领效力着实低下,就当是举一反三吧,迎接留言)
代码:

if(!document.getElementsByClassName) {
    document.getElementsByClassName = function(className) {
    var ele = [],
        tags = document.getElementsByTagName("*");
    className = className.split(/\s+/);
    for(var i = 0; i < tags.length; i++) {
        for(var j = 0; j < className.length; j++) {
        //假如这个元素上有这个class且没在ele内里(重要防备多个class加在一个元素上推进去两次的状况)
            if(tags[i].className === className[j] && ele.indexOf(tags[i]) === -1) {
                ele.push(tags[i]);
            }
        }
    }
    return ele;
    }
}

第十一题

请写出代码输出效果

  if(!("a" in window)){
      var a = 1;
  }
  alert(a);

这题重要考核了变量的声明提拔,任何变量(es5中)的声明都邑提拔到当前作用域的顶端。所以这里的代码着实为:

  var a;
  if(!("a" in window)){
      a = 1;
  }
  alert(a);

所以,在if语句实行前a就已在window中了,所以这里会atert undefined

第十二题

请写出代码输出效果

var handle = function(a){
    var b = 3;
    var tmp = function(a){
        b = a + b;
        return tmp;
    }
    tmp.toString = function(){
        return b;
    }
    return tmp;
}
alert(handle(4)(5)(6));

我们来一步一步看:起首是handle(4),到这里,顺序最先运转,建立了一个tmp函数,同时把tmp函数的toString要领重写了,末了返回这个tmp函数。
注重tmp里的a不是传进去的4,不要把tmpahandlea搞混了,所以这里传的4啥也没干。

然后到第二步:handle(4)(5),这里就是实行了tmp函数,这个时刻tmp函数的a就是传进来的5,·b就是第一步函数实行的b即3(不懂为什么是3的同砚再去相识相识闭包吧),末了这个b就即是8。

第三部反复第二步8+6,末了b为14,javascript引擎末了自动挪用了toString返回b,所以效果是14。

第十三题

javscript表达式”[]==””的值是什么,为什么?

这题考核对js==运算符的相识,我们晓得==运算符假如双方值范例不一样会把它们转换为雷同范例的值再来比较。这题左侧是object范例,右侧是string范例,所以会把左侧的转化为string范例来比较,[].toString()就是''所以末了效果是true

第十四题

Js天生下面html,点击每一个li的时刻弹出1,2,3……
//li onclick事宜都能弹出当前被点击的index=?

<ul id="testUrl">
    <li>index=0</li>
    <li>index=1</li>
</ul>

这题直接根据请求天生对应的html,再给ul绑定个事宜,应用事宜代办监听是谁被点了,然后输出它们的序号和对应的内容,没啥难度。我的代码:

var ul=document.createElement("ul"),
    lis=[];
    ul.id="testUrl";
for(var i=0,li;i<2;i++){
    li=document.createElement("li");
    li.innerHTML="index="+i;
    ul.appendChild(li);
    lis.push(li);
}
ul.addEventListener("click",function(e){
    alert(lis.indexOf(e.target));
    alert(e.target.innerHTML)
});
document.body.appendChild(ul);

第十五题

map要领是ES5中新增的,请求为ES5以下的环境增加个map要领

个人以为只要对map要领够相识,天然就可以封装出来了。嘿嘿,不喜勿喷。给的链接虽然也有一个完成map的要领,然则用到了es5的for in不相符题目,所以我的代码:

if(!Array.prototype.map){
    Array.prototype.map=function(callback,context){
    var len=this.length,
        i=0,
        result=[];
    if (typeof callback !== "function") {
        throw new TypeError(callback + " is not a function");
    }
    context=context||window;
    for(;i<len;i++){
        this[i]!==undefined?result.push(callback.call(context,this[i],i,this)):result.push(this[i]);
    }
    return result;
    }
}

不过我的代码和规范的输出效果照样有点相差的。就是我不处置惩罚undefinednull,由于this[i]!==undefined,这两个值是会原样返回的。不过一样平常的一些需求照样能满足的。迎接人人提发起哈。

终究打完了,这期就这么多题,愿望能对人人有协助,同时假如有不对的地方请实时斧正,迎接留言。

别的,迎接人人来围观我封装的一个ajax库 lightings

参考

JS随机打乱数组的要领小结
怎样不运用loop轮回,建立一个长度为100的数组,而且每一个元素的值即是它的下标
MDN map

    原文作者:JayZangwill
    原文地址: https://segmentfault.com/a/1190000008751374
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞