1、试题WEB前端常见试题汇总:( )1. JS找字符串中出现最多的字符例如:求字符串nininihaoa中出现次数最多字符var str = nininihaoa; var o = ;for (var i = 0, length = str.length; i length; i+) var char = str.charAt(i);if (ochar) ochar+; /次数加1 else ochar = 1; /若第次出现,次数记为1console.log(o); /输出的是完整的对象,记录着每个字符及其出现的次数/遍历对象,找到出现次数最多的字符的次数var max = 0;for (va
2、r key in o) if (max okey) max = okey; /max始终储存次数最的那个for (var key in o) if (okey = max) /console.log(key);console.log(最多的字符是 + key); console.log(出现的次数是 + max);法:结果如图所:var arrString = abcdaabc; arrString.split().reduce(function(res, cur) rescur ? rescur + : rescur = 1return res;, )法,当然还可以使reduce法来实现:想
3、详细了解reduce()法,可以参考:2. JS实现九九乘法表var sum=0; var wite;for (var i = 1; i 10; i+)var div=$();$(body).append(div);for(var j = i; j 0; j-) sum = j * i;wite = (j+X+i+=+sum);div.prepend($(+wite+);jQuery实现式:实现结果如图所:原js实现式: css代码:html,body,ul,li padding: 0;margin: 0;border: 0;ul width: 900px; overflow: hidden;
4、 margin-top: 4px; font-size: 12px; line-height: 36px;li float: left; width: 90px; margin: 0 4px;display: inline-block; text-align: center; border: 1px solid #333;background:yellowgreen;js代码:for(var i = 1; i = 9; i+)var myUl = document.createElement(ul); for(var j = 1; j = i; j+)var myLi = document.c
5、reateElement(li);var myText = document.createTextNode(j + + i + = + i*j); myLi.appendChild(myText);myUl.appendChild(myLi);document.getElementsByTagName(body)0.appendChild(myUl);原js实现效果如图所3. 前端试:这道前端试题很绕吗?做对了道?第题var fun = function() this.name = peter; return name: jack;var p = new fun();/请问p.name是:第题
6、var fun = function() this.name = peter;return jack;var p = new fun();/请问p.name是:第三题var fun = function() fun.prototype = info : name : peter, age : 25var a = new fun(); var b = new fun();a.info.name = jack; b.info.name = tom;/请问a.info.name和b.info.name分别是:第四题var fun = function() this.info = name : pet
7、er, age : 25var a = new fun(); var b = new fun();a.info.name = jack; b.info.name = tom;/请问a.info.name和b.info.name分别是:第五题var fun = function() fun.prototype = name : peter, age : 25var a = new fun(); var b = new fun();a.name = jack; b.name = tom;/请问a.name和b.name分别是:第六题var fun = function() this.info =
8、name : peter, age : 25fun.prototype = info : name : peter, age : 25var a = new fun(); var b = new fun();a.info.name = jack; b.info.name = tom;/请问a.info.name和b.info.name分别是:解答:1,2题考察的是构造函数的返回值的问题。每个函数都有返回值,如果使了return语句,则返回return后跟的值,如果没有使return,则默认返回undefined.特别的,如果这个函数是构造函数,则默认返回this对象,如果构造函数内使了retu
9、rn语句,并且return后跟的是个对象,则这个构造函数返回的是这个对 象,否则返回this.所以1题中的p = name: jack,2题中的p = name: peter.3, 4, 5, 6题都是考察prototype的知识。1. 先查找构造函数实例的属性或法,如果有,就即返回。2. 如果构造函数的实例没有,就去它的原型对象找,如果有,就即返回3. 两个都输出tom。先你要知道原型模式的执流程:4 .a.info.name 为jack,b.info.name为tom。原因我想你从第三题已经得出来了。5.a.name输出jack,b.name输出tom。原因我想你从第三题已经得出来了。6.
10、a.info.name 为jack,b.info.name为tom。原因我想你从第三题已经得出来了。注意:第三题 a.info.name这段代码,先去访问了实例对象本是否有info这个对象,发现没有就去原型上查找了,发现原型上有,所以地址共享了得到的值都是Tom;第五题是有区别的,a.name实例本没有,给当前a这个实例对象执赋值操作,没有去访问原型上的name。就相当于第 三题先访问了原型上的info对象,第五题没有访问过程,只是在实例上添加了name属性值。4. 通过例搞懂JS闭包例1function sayHello(name)var text = Hello + name;var sa
11、yAlert = function() console.log(text); sayAlert();sayHello(Bob) / 输出Hello Bob在sayHello()函数中定义并调了sayAlert()函数;sayAlert()作为内层函数,可以访问外层函数sayHello()中的text变量。例2function sayHello2(name)var text = Hello + name; / 局部变量var sayAlert = function() console.log(text); return sayAlert;var say2 = sayHello2(Jane); s
12、ay2(); / 输出Hello Jane例3function buildList(list) var result = ;for(var i = 0; i list.length; i+) var item = item + listi; result.push(function() console.log(item + + listi););return result;var fnlist = buildList(1,2,3);for (var j = 0; j fnlist.length; j+) fnlistj();得到的结果:连续输出3个item3 undefined解析:通过执bu
13、ildList函数,返回了个result,那么这个result存放的是3个匿名函数。然这三个匿名函数其实就是三个闭包,因为它可以访问到函数 的局部变量。所以闭包内的保留的i是最终的值为3.所以list3肯定是undefined. item变量值为item3.function buildList(list) var result = ;for(var i = 0; i list.length; i+) var item = item + listi; result.push(function(i) console.log(item + + listi);)(i);return result;va
14、r fnlist = buildList(1,2,3);改成如下代码:得到的结果:item1 1item2 2item3 3解释:这虽然传递了个数组进去,但是返回的是三个执的函数。例4function newClosure(someNum, someRef)var anArray = 1,2,3; var num = someNum; var ref = someRef; return function(x)num += x; anArray.push(num);console.log(num: + num + ; + anArray + anArray.toString() + ; + re
15、f.someVar + ref.someVar);closure1 = newClosure(40, someVar: closure 1); closure2 = newClosure(1000, someVar: closure 2);closure1(5); / 打印num: 45; anArray 1,2,3,45; ref.someVar closure 1closure2(-10); / 打印num: 990; anArray 1,2,3,990; ref.someVar closure 2每次调newClosure()都会创建独的闭包,它们的局部变量num与ref的值并不相同。例
16、5function sayAlice()var sayAlert = function() console.log(alice); var alice = Hello Alice;return sayAlert;var sayAlice2 = sayAlice(); sayAlice2(); / 输出Hello Alicealice变量在sayAlert函数之后定义,这并未影响代码执。因为返回函数sayAlice2所指向的闭包会包含sayAlice()函数中的所有局部变量,这然包括了alice 变量,因此可以正常打印”Hello Alice”。例6function setupSomeGloba
17、ls() var num = 666;gAlertNumber = function() console.log(num); gIncreaseNumber = function() num+; gSetNumber = function(x) num = x; setupSomeGlobals(); gAlertNumber(); / 输出666 gIncreaseNumber(); gAlertNumber(); / 输出667 gSetNumber(5); gAlertNumber(); / 输出5解释:先gAlertNumber,gIncreaseNumber,gSetNumber是三
18、个全局变量,并且其三个值都是匿名函数,然这三个匿名函数本都是闭包。他们操 作的num都是保存在内存中的同个num,所有会得出上的结果。/ 这个代码是错误的,因为变量i从来就没背locked住/ 相反,当循环执以后,我们在点击的时候i才获得数值/ 因为这个时候i操真正获得值/ 所以说论点击那个连接,最终显的都是I am link #10(如果有10个a元素的话)var elems = document.getElementsByTagName(a); for (var i = 0; i elems.length; i+) elemsi.addEventListener(click, functi
19、on (e) e.preventDefault();alert(I am link # + i);, false);/ 这个是可以的,因为他在执函数表达式闭包内部/ i的值作为locked的索引存在,在循环执结束以后,尽管最后i的值变成了a元素总数(例如10)/ 但闭包内部的lockedInIndex值是没有改变,因为他已经执完毕了/ 所以当点击连接的时候,结果是正确的var elems = document.getElementsByTagName(a); for (var i = 0; i elems.length; i+) (function (lockedInIndex) elemsi
20、.addEventListener(click, function (e) e.preventDefault();alert(I am link # + lockedInIndex);, false);)(i);/ 你也可以像下这样应,在处理函数那使执函数表达式/ 不是在addEventListener外部下看个dom操作,使闭包的例:/ 但是相对来说,上的代码更具可读性var elems = document.getElementsByTagName(a); for (var i = 0; i 0) repeatedString += string; times-;return repeat
21、edString;repeatStringNumTimes(abc, 3);不过这还可以有个变种:function repeatStringNumTimes(string, times) var repeatedArr = ; /while (times 0) repeatedArr.push(string); times-;return repeatedArr.join();repeatStringNumTimes(abc, 3)对于前端来说,先个可能会将字符串拼接,修改为 数组join()拼接字符串,例如:很多前端都有数组join()拼接字符串的“情怀”,因为很早以前普遍认为数组join(
22、)拼接字符串字符串+拼接速度要快得多。不过现在未必,例如,V8 下+拼接字符串,要数组join()拼接字符串快。我这两个法测试了3万次重复输出,只相差了毫秒。另个变种可以 for 循环:function repeatStringNumTimes(string, times) var repeatedString = ;for(var i = 0; i times ;i+) repeatedString += string;return repeatedString;repeatStringNumTimes(abc, 3)法2 : 通过条件判断和递归重复输出个字符串function repeat
23、StringNumTimes(string, times) if(times 0)return string.repeat(times); elsereturn ;repeatStringNumTimes(abc, 3);您可以使三元表达式作为 if/else 语句的快捷式,如下所:function repeatStringNumTimes(string, times) return times 0 ? string.repeat(times) : ;repeatStringNumTimes(abc, 3);6. 函数声明相关var x=1, y=0, z=0;function add(n)
24、n=n+1;y=add(x); z=x+y;console.log(y1:+y);console.log(z1:+z);function add(n) n=n+3;y=add(x); z=x+y;console.log(y2:+y);console.log(z2:+z);求y,z的值。结果为:y1:undefined z1:NaN y2:undefined z2:NaNvar x=1, y=0, z=0;function add(n) return n=n+1;y=add(x); z=x+y;console.log(y1:+y);console.log(z1:+z);function add(
25、n) return n=n+3;y=add(x); z=x+y;console.log(y2:+y);console.log(z2:+z);变化下:求y,z的值答案:y1:4 z1:5 y2:4 z2:57. 作域范围(Scope)(function()var a = b = 5;)();console.log(b);思考以下代码:控制台(console)会打印出什么?答案上述代码会打印出5。这个问题的陷阱就是,在即执函数表达式(IIFE)中,有两个命名,但是其中变量是通过关键词var来声明的。这就意味着a是这个函数的局部变量。与此相 反,b是在全局作域下的。这个问题另个陷阱就是,在函数中他没
26、有使严格模式(usestrict;)。如果严格模式开启,那么代码就会报出未捕获引错误(Uncaught ReferenceError):b没有定义。记住,严格模式要求你在需要使全局变量时,明确地引该变量。因此,你需要像下这么写:(function() use strictvar a = window.b = 5;)();console.log(b);再看如下个例:var a = 6; setTimeout(function () alert(a); a = 666;, 1000);a = 66;结果:668. 创建 “原(native)” 法console.log(hello.repeatif
27、y(3);在 String 对象上定义个 repeatify 函数。这个函数接受个整数参数,来明确字符串需要重复次。这个函数要求字符串重复指定的次数。举个例:应该打印出hellohellohello. 答案:String.prototype.repeatify = String.prototype.repeatify | function(times) var str = ;for (var i = 0; i times; i+) str += this;return str;String.prototype.repeatify = String.prototype.repeatify | f
28、unction(times)/*code here*/;在这,另个关键点是,看你怎样避免重写可能已经定义了的法。这可以通过在定义的法之前,检测法是否已经存在。当你需要为旧浏览器实现向后兼容的函数时,这技巧分有。9. 变量提升(Hoisting)function test() console.log(a); console.log(foo();var a = 1; function foo() return 2;test();执以下代码的结果是什么?为什么?答案:这段代码的执结果是undefined 和 2。这个结果的原因是,变量和函数都被提升(hoisted)到了函数体的顶部。因此,当打印变量
29、a时,它虽存在于函数体(因为a已经被声明),但仍然 是undefined。换之,上的代码等同于下的代码:function test() var a;function foo() return 2;console.log(a); console.log(foo();a = 1;test();再看如下代码:(function() console.log(typeof foo); console.log(typeof bar);var foo = hello, bar = function() return world;function foo() return hello;();function
30、undefined结果:10. 在javascript中,this是如何作的var fullname = John Doe; var obj = fullname: Colin Ihrig, prop: fullname: Aurelio De Rosa, getFullname: function() return this.fullname;console.log(obj.prop.getFullname(); var test = obj.prop.getFullname; console.log(test();以下代码的结果是什么?请解释你的答案。答案:这段代码打印结果是:Aureli
31、o De Rosa 和 John Doe 。原因是,JavaScript中关键字this所引的是函数上下,取决于函数是如何调的,不是怎么被定义的。在第个console.log(),getFullname()是作为obj.prop对象的函数被调。因此,当前的上下指代后者,并且函数返回这个对象的fullname属性。相反, 当getFullname()被赋值给test变量时,当前的上下是全局对象window,这是因为test被隐式地作为全局对象的属性。基于这点,函数返回window的fullname,在本例中即为第代码设置的。11. call() 和 apply()修复前个问题,让最后个conso
32、le.log() 打印输出Aurelio De Rosa. 答案:console.log(test.call(obj.prop);这个问题可以通过运call()或者apply()法强制转换上下环境。12. 闭包(Closures)var nodes = document.getElementsByTagName(button); for (var i = 0; i nodes.length; i+) nodesi.addEventListener(click, function() console.log(You clicked element # + i););考虑下的代码:请问,如果户点击
33、第个和第四个按钮的时候,控制台分别打印的结果是什么?为什么? 答案:两次打印都是nodes.length的值。那么修复上题的问题,使得点击第个按钮时输出0,点击第个按钮时输出1,依此类推。 有多种办法可以解决这个问题,下主要使两种法解决这个问题。第个解决案使即执函数表达式(IIFE)再创建个闭包,从得到所期望的i的值。实现此法的代码如下:var nodes = document.getElementsByTagName(button); for (var i = 0; i nodes.length; i+) nodesi.addEventListener(click, (function(i)
34、 return function() console.log(You clicked element # + i);)(i);function handlerWrapper(i) return function() console.log(You clicked element # + i);var nodes = document.getElementsByTagName(button); for (var i = 0; i nodes.length; i+) nodesi.addEventListener(click, handlerWrapper(i);另个解决案不使IIFE,是将函数移
35、到循环的外。这种法由下的代码实现:代码段:var name = The Window; var object = name : My Object, getNameFunc : function()return function()return this.name;alert(object.getNameFunc()();结果:The Windowvar name = The Window; var object = name : My Object, getNameFunc : function()var that = this; return function()return that.n
36、ame;alert(object.getNameFunc()();代码段:结果:My Object章地址:13. 数据类型问题console.log(typeof null); console.log(typeof ); console.log(typeof ); console.log(typeof undefined);考虑如下代码:答案:object object object undefined14. 事件循环function printing() console.log(1);setTimeout(function() console.log(2); , 1000); setTime
37、out(function() console.log(3); , 0); console.log(4);printing();下代码运结果是什么?请解释。答案:1432想知道为什么输出顺序是这样的,你需要弄了解setTimeout()做了什么,以及浏览器的事件循环原理。浏览器有个事件循环于检查事件队列,处理延迟的事 件。UI事件(例如,点击,滚动等),Ajax回调,以及提供给setTimeout()和setInterval()的回调都会依次被事件循环处理。因此,当调setTimeout()函数时,即使延迟的时间被设置为0,提供的回调也会被排队。回调会呆在队列中,直到指定的时间完后,引擎开始执动作(如果它在当前不执其他的动 作)。因此,即使setTimeout()回调被延迟0毫秒,它仍然会被排队,并且直到函数中其他延迟的语句被执完了之后,才会执。15. 算法问题写个isPrime()函数,当其为质数时返回true,否则返回false。答案:我认为这是试中最常见的问题之。然,尽管这个问题经常出现并且也很简单,但是从被试提供的答案中能很好地看出被试的数学和算法平。先, 因为JavaScript不同于C或者Java,因此你不能信任传递来的数据类型。如果试官没有明确地告诉你,你应该