都说机会是留给有准备的人的。
一年之计在于春,面对众多的前端技术,需要时刻充电自己。
我现在整理一些前端js面试程序题。
1.判断一个字符串中出现最多的字符,并计算出现的次数?
2.用css伪类实现下面的效果
<!DOCTYPE html> <html> <head> <title>button</title> <style type="text/css"> button{background:#000;color:#fff;border:0;width:150px;height:50px;position:relative;} button:after{ /*content:url(); posittion:absolute; right:0; top:10px;*/ content:''; width:30px; height:30px; border-radius:30px; background:#fff; display:block; position:absolute; right:-15px; top:10px; } </style> </head> <body> <button>button</button> </body> </html> <script> var str='asdfssaaasasasasaa'; var json={}; for(var i=0;i<str.length;i++){ if(!json[str.charAt(i)]){ console.log(str.charAt(i)); json[str.charAt(i)]=1; }else{ json[str.charAt(i)]++; document.write(json[charAt(i)); } }; var iMax=0; var iIndex=''; for(var i in json){ if(json[i]>iMax){ iMax=json[i]; iIndex=i; } } console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'次'); </script>
解释: 1. 针对css伪类元素,可以使用content:url();引入一个图片进行实现,也可以使用“content:' ' ”,设置块状元素实现,并使用定位
2.charAt(i)函数是获取字符串i位置的字符,console.log(str.charAt(i)),可输出a,s,d,f等字符
if(!json[str.charAt(i)])首先得到位置的字符char再判断json【char】是否存在,如果不存在就赋值为1,如果存在就加1,
document.write(json[charAt(i));输出json[char]当前的值
var iMax=0;
var iIndex='';
for(var i in json){
if(json[i]>iMax){
iMax=json[i];
iIndex=i;
}
比较一组数,并求出最大值,并输出这个值
3.编写一个方法,去掉一个数组的重复元素
列举两种实现方法:
1.
<script> /**第1种**/ var arr=[0,2,3,4,4,0,2]; var obj={}; var tmp=[]; for(var i=0;i<arr.length;i++){ if(!obj[arr[i]]){ obj[arr[i]]=1; tmp.push(arr[i]); } } console.log(tmp);//[0,2,3,4] /**第2种**/ var arr=[2,3,4,4,5,2,3,6]; arr2=[]; for(var i=0;i<arr.length;i++){ if(arr2.indexOf(arr[i])<0){ arr2.push(arr[i]); } } console.log(arr2);//[2,3,4,5,6] </script>
indexOf()可返回某个指定的字符串值在字符串中首次出现的位置
4.使用纯js实现一组列表所在的索引值
<body> <ul> <li>test1</li> <li>test2</li> <li>test3</li> <li>test4</li> <li>test5</li> <li>test6</li> <li>test7</li> <li>test8</li> <li>test9</li> <li>test10</li> </ul> <script> var lis = document.querySelectorAll('ul li'); /**1. 使用let 获取索引 for(let i = 0, len = lis.length; i < len; i++) { lis[i].addEventListener('click', function () { console.log(i); }, false); } **/ /**2. 立即执行函数来切断闭包对外部变量i的引用 for(var i = 0, len = lis.length; i < len; i++) { (function(i){ lis[i].addEventListener('click', function () { console.log(i); }, false); })(i) } **/
/**3.**/
var ul = document.querySelector('ul'); var lis = document.querySelectorAll('ul li'); ul.addEventListener('click', function (e) { var target = e.target; if(target.nodeName.toLowerCase() === 'li') { console.log([].indexOf.call(lis, target)); } }, false); </script> </body>
5.判断输入的值是否为数字
<html> <input type="text" id="tel" maxlength="11" onkeypress="checkint()" onkeyup="value=value.replace(/\D/g,'')"/> <script> function checkint() { var v = window.event.keyCode; if (!(v >= 48 && v <= 57)) { window.event.keyCode = 0; window.event.returnValue = false; alert("not a number;") } } </script> </htm>
6.获取字符串中出现次数最少的字符,并输出,此时需要用到hash
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8"> <title>test</title> <script> // 获取字符串中出现次数最少的字符 function getRareChar(str) { let hash = {}; // 将各个字符名字、首次出现位置及出现次数存到hash表 for(let i = 0, len = str.length; i < len; i++) { // 如果hash[str[i]]不存在,则对其进行初始化 hash[str[i]] = hash[str[i]] || {index: i, count: 0}; hash[str[i]].count++; // count计数自增 } // 因为哈希表不好排序,将它转成数组 return Object.keys(hash).map(function (key) { return Object.assign({char: key}, hash[key]); // 根据count属性进行升序排序 }).sort(function (a, b) { return a.count - b.count; // 取出count最小的 }).filter(function (e, i, arr) { return e.count === arr[0].count; // 在count值最小的集合里面再根据index属性进行升序排序 }).sort(function (a, b) { return a.index - b.index; })[0].char; } // 测试数据 var str = 'ablfdasfdarleoeorwqajhfdsafdlladaasrjhehafdalhewadadfahwesaew'; alert(getRareChar(str)); </script> </head> <body> </body> </html>
7.js的delete方法如何使用
<script> var arr = [1, 2, 3]; delete arr[1] //arr[1] = undefined; console.log(arr); // [1, undefined × 1, 2] console.log(delete arr[1]) // true console.log(arr[1]); // undefined /**如果想使用console.log(1 in arr);就不能使用delete,此时需要赋值arr[1] = undefined; console.log(1 in arr) **/ </script>
8.你如何获取浏览器URL中查询字符串中的参数?
测试地址为:url?channelid=12333&name=xiaoming&age=23
实例如下:
function showWindowHref(){ var sHref = window.location.href; var args = sHref.split('?'); if(args[0] == sHref){ return ""; } var arr = args[1].split('&'); var obj = {}; for(var i = 0;i< arr.length;i++){ var arg = arr[i].split('='); obj[arg[0]] = arg[1]; } return obj; } var href = showWindowHref(); // obj console.log(href['name']); // xiaoming
9.常见兼容性问题?
* png24位的图片在iE6浏览器上出现背景,解决方案是做成PNG8.也可以引用一段脚本处理. * 浏览器默认的margin和padding不同。解决方案是加一个全局的*{margin:0;padding:0;}来统一。 * IE6双边距bug:块属性标签float后,又有横行的margin情况下,在ie6显示margin比设置的大。 * 浮动ie产生的双倍距离(IE6双边距问题:在IE6下,如果对元素设置了浮动,同时又设置了margin-left或margin-right,margin值会加倍。) #box{ float:left; width:10px; margin:0 0 0 100px;} 这种情况之下IE会产生20px的距离,解决方案是在float的标签样式控制中加入 ——_display:inline;将其转化为行内属性。(_这个符号只有ie6会识别) * 渐进识别的方式,从总体中逐渐排除局部。 首先,巧妙的使用“\9”这一标记,将IE游览器从所有情况中分离出来。 接着,再次使用“+”将IE8和IE7、IE6分离开来,这样IE8已经独立识别。 css .bb{ background-color:#f1ee18;/*所有识别*/ .background-color:#00deff\9; /*IE6、7、8识别*/ +background-color:#a200ff;/*IE6、7识别*/ _background-color:#1e0bd1;/*IE6识别*/ } * IE下,可以使用获取常规属性的方法来获取自定义属性, 也可以使用getAttribute()获取自定义属性; Firefox下,只能使用getAttribute()获取自定义属性. 解决方法:统一通过getAttribute()获取自定义属性. * IE下,event对象有x,y属性,但是没有pageX,pageY属性; Firefox下,event对象有pageX,pageY属性,但是没有x,y属性. * 解决方法:(条件注释)缺点是在IE浏览器下可能会增加额外的HTTP请求数。 * Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决. * 超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序: L-V-H-A : a:link {} a:visited {} a:hover {} a:active {} * 怪异模式问题:漏写DTD声明,Firefox仍然会按照标准模式来解析网页,但在IE中会触发怪异模式。为避免怪异模式给我们带来不必要的麻烦,最好养成书写DTD声明的好习惯。现在可以使用[html5](http://www.w3.org/TR/html5/single-page.html)推荐的写法:`<doctype html>` * 上下margin重合问题 ie和ff都存在,相邻的两个div的margin-left和margin-right不会重合,但是margin-top和margin-bottom却会发生重合。 解决方法,养成良好的代码编写习惯,同时采用margin-top或者同时采用margin-bottom。 * ie6对png图片格式支持不好(引用一段脚本处理)
到底在调用哪个函数?
再看下原题,现在知道了程序中有两个fun函数(第一个和第三个相同),遂接下来的问题是搞清楚,运行时他执行的是哪个fun函数?
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);//undefined,?,?,? var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,? //问:三行a,b,c的输出分别是什么?
1、第一行a
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
可以得知,第一个fun(0)是在调用第一层fun函数。第二个fun(1)是在调用前一个fun的返回值的fun函数,所以:
第后面几个fun(1),fun(2),fun(3),函数都是在调用第二层fun函数。
遂:
在第一次调用fun(0)时,o为undefined;
第二次调用fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0,并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用fun(2)时m为2,但依然是调用a.fun,所以还是闭包了第一次调用时的n,所以内部调用第一层的fun(2,0);所以o为0
第四次同理;
即:最终答案为undefined,0,0,0
2、第二行b
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
先从fun(0)开始看,肯定是调用的第一层fun函数;而他的返回值是一个对象,所以第二个fun(1)调用的是第二层fun函数,后面几个也是调用的第二层fun函数。
遂:
在第一次调用第一层fun(0)时,o为undefined;
第二次调用 .fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0,并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用 .fun(2)时m为2,此时当前的fun函数不是第一次执行的返回对象,而是第二次执行的返回对象。而在第二次执行第一层fun函数时时(1,0)所以n=1,o=0,返回时闭包了第二次的n,遂在第三次调用第三层fun函数时m=2,n=1,即调用第一层fun函数fun(2,1),所以o为1;
第四次调用 .fun(3)时m为3,闭包了第三次调用的n,同理,最终调用第一层fun函数为fun(3,2);所以o为2;
即最终答案:undefined,0,1,2
3、第三行c
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
根据前面两个例子,可以得知:
fun(0)为执行第一层fun函数,.fun(1)执行的是fun(0)返回的第二层fun函数,这里语句结束,遂c存放的是fun(1)的返回值,而不是fun(0)的返回值,所以c中闭包的也是fun(1)第二次执行的n的值。c.fun(2)执行的是fun(1)返回的第二层fun函数,c.fun(3)执行的也是fun(1)返回的第二层fun函数。
遂:
在第一次调用第一层fun(0)时,o为undefined;
第二次调用 .fun(1)时m为1,此时fun闭包了外层函数的n,也就是第一次调用的n=0,即m=1,n=0,并在内部调用第一层fun函数fun(1,0);所以o为0;
第三次调用 .fun(2)时m为2,此时fun闭包的是第二次调用的n=1,即m=2,n=1,并在内部调用第一层fun函数fun(2,1);所以o为1;
第四次.fun(3)时同理,但依然是调用的第二次的返回值,遂最终调用第一层fun函数fun(3,1),所以o还为1
即最终答案:undefined,0,1,1