原文地址&&个人博客
知乎&&知乎专栏
简书
河南前端交流群官网javascript
上次写了一篇几个让我印象深入的面试题(一)没看过的同窗能够去看哦。
此次文章的题目来源:这里有超过20家的前端面试题,你肯定不点进来看看?。
若是上面的问题在我这篇文章里没有提到的话,那就说明有些问题能够很容易查获得或者很简单或者我能力有限不能解答出来的。若是有的问题你不会并且我又没有提的那就认为就是我能力有限不能解答出来吧。嘿嘿嘿。开个玩笑,不过能够在下面留言哦!html
仍是老规矩先给题目,而后在看个人答案,有什么意见能够在留言板提。前端
请问a,b,c分别输出什么?java
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);
用尽量多的方法找出数组中重复出现过的元素git
例如:[1,2,4,4,3,3,1,5,3]es6
输出:[1,3,4]github
给定一些文档(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
下面代码会输出什么?ajax
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));
不用循环,建立一个长度为 100 的数组,而且每一个元素的值等于它的下标。正则表达式
一个整数,它的各位数字若是是左右对称的,则这个数字是对称数。那么请找出 1 至 10000 中全部的对称数
如下代码输出结果是什么?
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();
请写出如下正则表达式的详细规则说明
/^(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
请写出打乱数组方法
写出element.getElementsByClassName 的实现方法
请写出代码输出结果
if(!("a" in window)){ var a = 1; } alert(a);
请写出代码输出结果
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));
javscript表达式"[]==''"的值是什么,为何?
Js生成下面html,点击每一个li的时候弹出1,2,3......
//li onclick事件都能弹出当前被点击的index=?
<ul id="testUrl"> <li>index=0</li> <li>index=1</li> </ul>
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
方法遍历数组,由于它能一次取到两个数而后a
和b
比较若是相等并且result
里面又没有重复的就把a
推动去。
这是个人代码:
感谢@倔强的小瓶盖同窗指出的问题
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; }
感谢@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思路解说:
使用indexOf
和lastIndexOf
正向判断和反向判断这个元素是否是同一个数(若是是同一个数,则两个方法返回的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.keys和Array.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
输出的foo
是undefined
由于在window
下foo
没定义。第四个输出的是self.foo
这个self
就是上面定义的self
即myObject
因此,这里的foo
为bar
。
请写出如下正则表达式的详细规则说明
/^(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}})不符合
请写出打乱数组方法
// 以前的问题代码 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,不要把tmp
的a
和handle
的a
搞混了,因此这里传的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; } }
不过个人代码和标准的输出结果仍是有点出入的。就是我不处理undefined
和null
,由于this[i]!==undefined
,这两个值是会原样返回的。不过平常的一些需求仍是能知足的。欢迎你们提建议哈。
终于打完了,这期就这么多题,但愿能对你们有帮助,同时若是有不对的地方请及时指正,欢迎留言。
另外,欢迎你们来围观我封装的一个ajax库 lightings。
JS随机打乱数组的方法小结
如何不使用loop循环,建立一个长度为100的数组,而且每一个元素的值等于它的下标
MDN map