您的位置:首页 > Web前端 > JavaScript

BAT及各大互联网公司2014前端笔试面试题--JavaScript篇

2014-10-16 22:10 896 查看
  很多面试题是我自己面试BAT亲身经历碰到的。整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习js更是大有裨益。

  而更多的题目是我一路以来收集的,也有往年的,答案不确保一定正确,如有错误或有更好的解法,还请斧正。

  附上第二篇:BAT及各大互联网公司2014前端笔试面试题--Html,Css篇

  前面几题是会很基础,越下越有深度。

  

  初级Javascript:

  1.JavaScript是一门什么样的语言,它有哪些特点?

  没有标准答案。

  

  2.JavaScript的数据类型都有什么?

  基本数据类型:String,Boolean,Number,Undefined, Null

  引用数据类型:Object(Array,Date,RegExp,Function)

  

  那么问题来了,如何判断某变量是否为数组数据类型?

方法一.判断其是否具有“数组性质”,如slice()方法。可自己给该变量定义slice方法,故有时会失效

方法二.obj instanceof Array 在某些IE版本中不正确

方法三.方法一二皆有漏洞,在ECMA Script5中定义了新方法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”


  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"。

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;
}


  (考察基础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 = istart - iend +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,实在基础,没细写每一步)

  1)创建新节点

createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点

  2)添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入

  3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性

  

  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);
};


  答案:4 4 4。

  原因: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
){
return result
;
}else{
//argument.callee()表示fn()
result
=arguments.callee(n-1)+arguments.callee(n-2);
return result
;
}
}
}


  中级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;
}

//方法二:
/**
* 克隆一个对象
* @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];
function deRepeat(){
var newArr=[];
var obj={};
var index=0;
var l=arr.length;
for(var i=0;i<l;i++){
if(obj[arr[i]]==undefined)
{
obj[arr[i]]=1;
newArr[index++]=arr[i];
}
else if(obj[arr[i]]==1)
continue;
}
return newArr;

}
var newArr2=deRepeat(arr);
alert(newArr2); //输出1,2,3,4,5,6,9,25


  3.小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:

function Dog() {
this.wow = function() {
alert(’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 lis=document.getElementById('2223').getElementsByTagName('li');
for(var i=0;i<3;i++)
{
lis[i].index=i;
lis[i].onclick=function(){
alert(this.index);
};
}

//方法二:
var lis=document.getElementById('2223').getElementsByTagName('li');
for(var i=0;i<3;i++)
{
lis[i].index=i;
lis[i].onclick=(function(a){
return function() {
alert(a);
}
})(i);
}


  5.编写一个JavaScript函数,输入指定类型的选择器(仅需支持id,class,tagName三种简单CSS选择器,无需兼容组合选择器)可以返回匹配的DOM节点,需考虑浏览器兼容性和性能。

  /*** @param selector {String} 传入的CSS选择器。* @return {Array}*/

  答案:(过长,点击打开)

ajax({
url: "./TestXHR.aspx",              //请求地址
type: "POST",                       //请求方式
data: { name: "super", age: 20 },        //请求参数
dataType: "json",
success: function (response, xml) {
// 此处放成功后执行的代码
},
fail: function (status) {
// 此处放失败后执行的代码
}
});

function ajax(options) {
options = options || {};
options.type = (options.type || "GET").toUpperCase();
options.dataType = options.dataType || "json";
var params = formatParams(options.data);

//创建 - 非IE6 - 第一步
if (window.XMLHttpRequest) {
var xhr = new XMLHttpRequest();
} else { //IE6及其以下版本浏览器
var xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

//接收 - 第三步
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var status = xhr.status;
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText, xhr.responseXML);
} else {
options.fail && options.fail(status);
}
}
}

//连接 和 发送 - 第二步
if (options.type == "GET") {
xhr.open("GET", options.url + "?" + params, true);
xhr.send(null);
} else if (options.type == "POST") {
xhr.open("POST", options.url, true);
//设置表单提交时的内容类型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(params);
}
}
//格式化参数
function formatParams(data) {
var arr = [];
for (var name in data) {
arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
}
arr.push(("v=" + Math.random()).replace("."));
return arr.join("&");
}


View Code
  上述代码大致表述了ajax的过程,释义自行google,问题未完,那么知道什么是Jsonp和pjax吗?

  答案:

  Jsonp:(JSON with Padding)是一种跨域请求方式。主要原理是利用了script 标签可以跨域请求的特点,由其 src 属性发送请求到服务器,服务器返回 js 代码,网页端接受响应,然后就直接执行了,这和通过 script 标签引用外部文件的原理是一样的。JSONP由两部分组成:回调函数和数据,回调函数一般是由网页端控制,作为参数发往服务器端,服务器端把该函数和数据拼成字符串返回。

  pjax:pjax是一种基于ajax+history.pushState的新技术,该技术可以无刷新改变页面的内容,并且可以改变页面的URL。(关键点:可以实现ajax无法实现的后退功能)pjax是
ajax
+
pushState
的封装,同时支持本地存储、动画等多种功能。目前支持jquery、qwrap、kissy等多种版本。

  觉得题目还ok的亲点个推荐哦,题量会不断增加。

  你可能会感兴趣:BAT及各大互联网公司2014前端笔试面试题--Html,Css篇

  暂且贴出我做出答案的部分。有时间把未做出答案也贴出来。针对文中各题,如有更好的解决方法或者错误之处,各位亲务必告知我,误人子弟实乃罪过。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: