BAT及各大互联网公司2014前端笔试面试题:JavaScript篇
一、初级JavaScript
1.JavaScript是一门什么样的语言,它有哪些特点?
没有标准答案。
2.JavaScript的数据类型都有什么?
基本数据类型:String,Boolean,Number,Undefined, Null
引用数据类型:Object(Array,Date,RegExp,Function)
那么问题来了,如何判断某变量是否为数组数据类型?
var arr=[1,2]
- 方法一:arr instanceof Array //true
- 方法二:Object.prototype.toString.apply(arr) //"[object Array]" //ECMA5
- 方法三:arr.constructor //function Array() { [native code] } constructor可以被修改,可能失效。
- 方法四:duck type 判断是否有slice()方法 可以给变量自定义slice方法,所以可能失效。
低版本模拟Array的isArray方法:
if(typeof Array.isArray==="undefined") { Array.isArray = function(arg){ return Object.prototype.toString.call(arg)==="[object Array]" }; }
3.已知ID的Input输入框,希望获取这个输入框的输入值,怎么做?(不使用第三方框架)
document.getElementById('ID').value
4.希望获取到页面中所有的checkbox怎么做?(不使用第三方框架)
var domList = document.getElementsByTagName('input'); var checkBoxList = []; var len = domList.length; //缓存到局部变量 while (len--) { //使用while的效率会比for循环更高 if (domList[len].type == 'checkbox') { checkBoxList.push(domList[len]); } }
5.设置一个已知ID的DIV的html内容为xxxx,字体颜色设置为黑色(不使用第三方框架)
var dom = document.getElementById(“ID”); dom.innerHTML = “xxxx”; dom.style.color = “#000”;
- 方法一:dom.innerHTML="bbb";
- 方法二:dom.innerText="aaa";
- 方法三:dom.textContent="ccc";
6.当一个DOM节点被点击时候,我们希望能够执行一个函数,应该怎么做?
- 直接在DOM里绑定事件:<div onclick=”test()”></div>
- 在JS里通过onclick绑定:xxx.onclick = test
- 通过事件添加进行绑定:addEventListener(xxx, ‘click’, test)
那么问题来了,Javascript的事件流模型都有什么?
- “事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
- “事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
- “DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡
7.什么是Ajax和JSON,它们的优缺点。
Ajax是异步JavaScript和XML,用于在Web页面中实现异步数据交互。
优点:
- 可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量
- 避免用户不断刷新或者跳转页面,提高用户体验
缺点:
- 对搜索引擎不友好
- 要实现ajax下的前进后退功成本较大
- 可能造成请求数的增加
- 跨域问题限制
JSON是一种轻量级的数据交换格式,ECMA的一个子集
有点:轻量级,易于人的阅读和编写,便于JavaScript解析,支持符合数据类型(数组、对象、字符串、数字)
8.看下列代码输出为何?解释原因。
var a; alert(typeof a); // undefined alert(b); // 报错
解释:Undefined是一个只有一个值的数据类型,这个值就是“undefined”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是undefined。而b由于未声明将报错。注意未申明的变量和声明了未赋值的是不一样的。
9.看下列代码,输出什么?解释原因。
var a = null; alert(typeof a); //object
解释:null是以只有一值的数据类型,这个值就是null。表示一个空指针对象,所以用typeof检测会返回"object"。
10.看下列代码,输出什么?解释原因。
var undefined; undefined == null; // true 1 == true; // true 2 == true; // false 0 == false; // true 0 == ''; // true NaN == NaN; // false [] == false; // true [] == ![]; // true
- undefined与null相等,但不恒等(===)
- 一个是number一个是string时,会尝试将string转换为number
- 尝试将boolean转换为number,0或1
- 尝试将Object转换成number或string,取决于另外一个对比量的类型
- 所以,对于0、空字符串的判断,建议使用 “===” 。“===”会先判断两边的值类型,类型不匹配时为false。
那么问题来了,看下面的代码,输出什么,foo的类型为什么?
var foo = "11"+2-"1"; console.log(foo); console.log(typeof foo);
执行完后foo的值为111,foo的类型为Number。
var foo = "11"+2+"1"; //体会加一个字符串'1' 和 减去一个字符串'1'的不同 console.log(foo); console.log(typeof foo);
执行完后foo的值为1121(此处是字符串拼接),foo的类型为String。
11.看代码给答案。
var a = new Object(); a.value = 1; b = a; b.value = 2; alert(a.value);
答案:2(考察引用数据类型细节)
12.已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”。
答案:alert(stringArray.join(" "))
那么问题来了,已知有字符串foo="get-element-by-id",写一个function将其转化成驼峰表示法"getElementById"。
原作者:
var foo="get-element-by-id"; function combo(msg){ var arr = msg.split("-"); var len = arr.length; //将arr.length存储在一个局部变量可以提高for循环效率 for(var i=1;i<len;i++){ arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1); } msg=arr.join(""); return msg; } combo(foo); //"getElementById"
我写的:
function myCombo(msg){ var arr=msg.split('-'); var len=arr.length; var str=arr[0]; for(var i=1;i<len;i++){ str+=arr[i].charAt(0).toUpperCase().concat(arr[i].slice(1)); } return str; } myCombo(foo); //"getElementById"
(考察基础API)
13.var numberArray = [3,6,2,4,1,5]; (考察基础API)
1) 实现对该数组的倒排,输出[5,1,4,2,6,3]
2) 实现对该数组的降序排列,输出[6,5,4,3,2,1]
var numberArray = [3,6,2,4,1,5]; numberArray.reverse(); // 5,1,4,2,6,3 numberArray.sort(function(a,b){ //6,5,4,3,2,1 return b-a; })
14.输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26
var d = new Date(); // 获取年,getFullYear()返回4位的数字 var year = d.getFullYear(); // 获取月,月份比较特殊,0是1月,11是12月 var month = d.getMonth() + 1; // 变成两位 month = month < 10 ? '0' + month : month; // 获取日 var day = d.getDate(); day = day < 10 ? '0' + day : day; alert(year + '-' + month + '-' + day);
15.将字符串”<tr><td>{$id}</td><td>{$name}</td></tr>”中的{$id}替换成10,{$name}替换成Tony (使用正则表达式)
答案:”<tr><td>{$id}</td><td>{$id}_{$name}</td></tr>”.replace(/{\$id}/g, ’10’).replace(/{\$name}/g, ‘Tony’);
16.为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义
function escapeHtml(str) { return str.replace(/[<>”&]/g, function(match) { switch (match) { case “<”: return “<”; case “>”: return “>”; case “&”: return “&”; case “\””: return “"”; } }); }
17.foo = foo||bar ,这行代码是什么意思?为什么要这样写?
答案:if(!foo) foo = bar; //如果foo存在,值不变,否则把bar的值赋给foo。
短路表达式:作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。
18.看下列代码,将会输出什么?(变量声明提升)
var foo = 1; function(){ console.log(foo); var foo = 2; console.log(foo); }
答案:输出undefined 和 2。上面代码相当于:
var foo = 1; function(){ var foo; console.log(foo); //undefined foo = 2; console.log(foo); // 2; }
函数声明与变量声明会被JavaScript引擎隐式地提升到当前作用域的顶部,但是只提升名称不会提升赋值部分。
19.用js实现随机选取10--100之间的10个数字,存入一个数组,并排序。
var iArray = []; funtion getRandom(istart, iend){ var iChoice = iend - istart +1; return Math.floor(Math.random() * iChoice + istart); } for(var i=0; i<10; i++){ iArray.push(getRandom(10,100)); } iArray.sort();
20.把两个数组合并,并删除第二个元素。
var array1 = ['a','b','c']; var bArray = ['d','e','f']; var cArray = array1.concat(bArray); cArray.splice(1,1);
21.怎样添加、移除、移动、复制、创建和查找节点(原生JS,实在基础,没细写每一步)
了解更多可参考:DOM
1)创建新节点
- createElement()//创建一具体的元素
- createTextNode()//创建一个文本节点
- createDocumentFragment()//创建一个DOM片段
2)添加、移除、替换、插入
- appendChild() //添加
- removeChild() //移除
- replaceChild() //替换
- insertBefore() //
在已有的子节点前插入一个新的子节点
3)查找
- getElementsByTagName() //通过标签名称
- getElementsByName() //通过元素的Name属性的值
(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
- getElementById() //通过元素Id,唯一性
- getElementsByClassName() //通过类名查找
- childNodes保存子节点的引用,包括空白也在内(除了IE<9),也包括<script>在内。
- children如果只想获得子节点中的元素节点,跳过文本节点,应该使用children属性。
- firstChild和lastChild是childNodes中首尾节点的快速索引。
- parentNode,previousSibling和nextSibling
- document.documentElement和document.body。
22.有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:'1', b:'2', c:'', d:'xxx', e:undefined}。
答案:
function serilizeUrl(url) { var result = {}; url = url.split("?")[1]; var map = url.split("&"); for(var i = 0, len = map.length; i < len; i++) { result[map[i].split("=")[0]] = map[i].split("=")[1]; } return result; }
23.正则表达式构造函数var reg=new RegExp("xxx")与正则表达字面量var reg=//有什么不同?匹配邮箱的正则表达式?
答案:当使用RegExp()构造函数的时候,不仅需要转义引号(即\"表示"),并且还需要双反斜杠(即\\表示一个\)。使用正则表达字面量的效率更高。
邮箱的正则匹配:
var regMail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/;
24.看下面代码,给出输出结果。
for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i); },0); };
原因:Javascript事件处理器在线程空闲之前不会运行。那么问题来了,如何让上述代码输出1 2 3?
for(var i=1;i<=3;i++){ setTimeout((function(a){ //改成立即执行函数 console.log(a); })(i),0); }; 1 //输出 2 3
25.写一个function,清除字符串前后的空格。(兼容所有浏览器)
使用自带接口trim(),考虑兼容性:
if (!String.prototype.trim) { String.prototype.trim = function() { return this.replace(/^\s+/, "").replace(/\s+$/,""); } } // test the function var str = " \t\n test string ".trim(); alert(str == "test string"); // alerts "true"
26.Javascript中callee和caller的作用?
答案:
caller是返回一个对函数的引用,该函数调用了当前函数;
callee是返回正在被执行的function函数,也就是所指定的function对象的正文。
那么问题来了?如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第n个月能繁殖成多少对兔子?(使用callee完成)
var result=[]; function fn(n){ //典型的斐波那契数列 if(n==1){ return 1; }else if(n==2){ return 1; }else{ if(result[n]){ return result[n]; }else{ //argument.callee()表示fn() result[n]=arguments.callee(n-1)+arguments.callee(n-2); return result[n]; } } }
二、中级JavaScript
1.实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
- 考察点1:对于基本数据类型和引用数据类型在内存中存放的是值还是指针这一区别是否清楚
- 考察点2:是否知道如何判断一个变量是什么类型的
- 考察点3:递归算法的设计
//方法一 Object.prototype.clone=function(){ var o=this.constructor===Array?[]:{}; for(var e in this){ o[e]=typeof this[e]==="object"?this[e].clone() :this[e]; } return o; } /* //test var person={ name:"lxy", class:"3", say:function(){ console.log("haha"); } } var persona=person.clone(); console.log(persona);*/
//方法二 /* *克隆一个对象 @param Obj @returns */ function clone(Obj){ var buf; if(Obj instanceof Array){ buf=[];//创建一空数组 var i=Obj.length; while(i--){ buf[i]=clone(Obj[i]); } return buf; }else if(Obj instanceof Object){ buf={};//创建一个空对象 for(var k in Obj){//为这个空对象添加新属性 buf[k]=clone(Obj[k]); } return buf; }else{//普通变量直接赋值 return Obj; } }
2.如何消除一个数组里面重复的元素?
var arr = [1, 2, 3, 3, 4, 4, 5, 5, 6, 1, 9, 3, 25, 4]; var arrB=[]; for(var i=0;i<arr.length;i++){ if(arrB.indexOf(arr[i])==-1){ arrB.push(arr[i]); } } arrB;//[1, 2, 3, 4, 5, 6, 9, 25]
//方法二 function derepeat(arr){ var obj={}; var newarr=[]; for(var i=0;i<arr.length;i++){ obj[arr[i]]=true; } for(o in obj){ newarr.push(o); } return newarr; }
3.小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:
function Dog(){ this.wow=function(){ console.log('wow'); } this.yelp=function(){ this.wow(); } }
小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实。(继承,原型,setInterval)
function MadDog() { this.yelp = function() { var self = this; setInterval(function() { self.wow(); }, 500); } } MadDog.prototype = new Dog(); //for test var dog = new Dog(); dog.yelp(); var madDog = new MadDog(); madDog.yelp();
4.下面这个ul,如何点击每一列的时候alert其index?(闭包)
<ul id="test"> <li>这是第一条</li> <li>这是第二条</li> <li>这是第三条</li> </ul>
答案:
//方法一 var lists=document.getElementById("test").getElementsByTagName("li"); var len=lists.length; for(var i=0;i<len;i++){ lists[i].onclick=function(i){ return function(){ alert(i); } }(i); }
//方法二 var lists=document.getElementById("test").getElementsByTagName("li"); var len=lists.length; for(var i=0;i<len;i++){ lists[i].index=i; lists[i].onclick=function(){ alert(this.index); }; }
5.编写一个JavaScript函数,输入指定类型的选择器(仅需支持id,class,tagName三种简单CSS选择器,无需兼容组合选择器)可以返回匹配的DOM节点,需考虑浏览器兼容性和性能。
参考链接:
http://www.cnblogs.com/coco1s/p/4029708.html
本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/4904929.html有问题欢迎与我讨论,共同进步。
如果觉得本文对您有帮助~可以
微信支持一下: