经典的前端 面试笔试题(二)

简介: 经典的前端 面试笔试题

(7)JavaScript变量提升

请看下面代码

var bar=1;
function test(){
  console.log(bar);     //undeifned
  var bar=2;
  console.log(bar);  //2
}
test();

为什么在test函数中会出现上述结果呢,这就是JavaScript的变量提升了,虽然变量bar的定义在后面,不过浏览器在解析的时候,会把变量的定义放到最前面,上面的test函数相当于

function test(){
  var bar;
  console.log(bar);   //undefined
  bar=2;
  console.log(bar);   //2
}

再看

var foo=function(){
  console.log(1);
 }
function foo(){
  console.log(2);
 }
foo();  //结果为1
//同样的,函数的定义也会到提升到最前面,上面的代码相当于
function foo(){
  console.log(2);
 }
var foo;foo=funciton(){
 console.log(1);
 }foo();   //1

(8)JavaScript事件模型

原始事件模型,捕获型事件模型,冒泡事件模型,

原始事件模型就是ele.onclick=function(){}这种类型的事件模型

冒泡事件模型是指事件从事件的发生地(目标元素),一直向上传递,直到document,

捕获型则恰好相反,事件是从document向下传递,直到事件的发生地(目标元素)

IE是只支持冒泡事件模型的,下面是兼容各个浏览器的事件监听代码

EventUtil={
  addListener:function(target,type,handler){
    if(target.addEventListener){
        target.addEventListener(type,handler);
    }else if(target.attachEvent){
        target.attach("on"+type,function(){
               //让handler中的this指向目标元素
              handler.call(target);
        });
    }else{
        target["on"+type]=handler;
    }
  },
removeListener:function(target,type,handler){   
      if(target.removeEventListener){    
        target.removeEventListener(type,handler);          
     }else if(target.detachEvent){
        target.detachEvent("on"+type,handler);
     }else{
        target["on"+type]=null;
     }
  },
getEvent:function(e){      //获取事件对象
     var evt=window.event||e;
     return evt;
},
getTarget:function(e){      //获得目标对象
     var evt=EventUtil.getEvent(e);
     var target;
     if(evt.target){ target=evt.target;}
     else {target=evt.srcElement;}
     return target;
},
stopPropagation:function(e){  //停止冒泡
     var evt=EventUtil.getEvent(e);
     if(evt.stopPropagation) {evt.stopPropagation();}
     else {evt.cancelBubble=true;}
},
preventDefault:function(e){   //阻值默认行为的发生
     var evt=EventUtil.getEvent(e);
     if(evt.preventDefault){ evt.preventDefault(); }
     else {e.returnValue=false;}
}
}

(9)内存泄漏

内存泄漏指的是浏览器不能正常的回收内存的现象

(10)浏览器的垃圾回收机制

垃圾收集器必须跟踪哪个变量有用哪个变量没用,对于不再有用的变量打上标记,以备将来收回其占用的内存,内存泄露和浏览器实现的垃圾回收机制息息相关, 而浏览器实现标识无用变量的策略主要有下两个方法:

第一,引用计数法

跟踪记录每个值被引用的次数。当声明一个变量并将引用类型的值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次 数加1.相反,如果包含对这个值引用的变量又取得另外一个值,则这个值的引用次数减1.当这个值的引用次数变成0时,则说明没有办法访问这个值了,因此就 可以将其占用的内存空间回收回来。

如: var a = {};     //对象{}的引用计数为1
     b = a;          //对象{}的引用计数为 1+1 
     a = null;       //对象{}的引用计数为2-1

所以这时对象{}不会被回收;

IE 6, 7 对DOM对象进行引用计数回收, 这样简单的垃圾回收机制,非常容易出现循环引用问题导致内存不能被回收, 进行导致内存泄露等问题,一般不用引用计数法。

第二,标记清除法

到2008年为止,IE,Firefox,Opera,Chrome和Safari的javascript实现使用的都是标记清除式的垃圾收集策略(或类似的策略),只不过垃圾收集的时间间隔互有不同。

标记清除的算法分为两个阶段,标记(mark)和清除(sweep). 第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。

(11)同源策略

同源策略是浏览器有一个很重要的概念。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。简单的来说,浏览器允许包含在页面A的脚本访问第二个页面B的数据资源,这一切是建立在A和B页面是同源的基础上。


(12)跨域的几种方式

jsonp(利用script标签的跨域能力)跨域、websocket(html5的新特性,是一种新协议)跨域、设置代理服务器(由服务器替我们向不同源的服务器请求数据)、CORS(跨源资源共享,cross origin resource sharing)、iframe跨域、postMessage(包含iframe的页面向iframe传递消息)

(13)异步和同步

同步指下一个程序的执行需要等到上一个程序执行完毕,也就是得出结果后下一个才能执行,

异步指的是上一个程序指向后,下一个程序不用等到上一个程序出结果就能执行,等上一个出结果了调用回调函数处理结果就好。

(14)JavaScript的值类型和引用类型

JavaScript有两种类型的数据,值类型和引用类型,一般的数字,字符串,布尔值都是值类型,存放在栈中,而对象,函数,数组等是引用类型,存放在堆中,对引用类型的复制其实是引用复制,相当于复制着地址,对象并没有真正的复制。

var a=5;var b=a;a=null;    //那么b是5
var a={},var b=a;b.name="mbj";
console.log(a.name);   //mbj,因为a,b指向同一个对象
a=null;console.log(typeof b);
//object,a=null,只是a不再指向该对象,
//但是这个对象还是在堆中确确实实的存在,b依然指向它。

(15)优化下面代码

var str="我喜欢我可爱的女朋友,";
str=str+"她叫喵喵,";
str=str+"她时而可爱,时而认真,";
str=str+"她那天真的笑声可以让人忘掉一切烦恼。";
console.log(str);

这里的优化主要是对加号操作符的优化,因为加号在JavaScript中非常耗时和耗内存,需要经过以下六步:

1、首先开辟一块临时空间,存储字符串,

2、然后在开辟一块空间3、把str中的字符串复制到刚刚开辟的空间

4、在把需要连接的字符串复制到str后面

5、str指向这块空间

6、回收str原来的空间和临时空间


优化的方法是使用数组的push方法,数组是连续的存储空间,可以省下很多步

var res=[];
var str="我喜欢我可爱的女朋友,";
res.push(str);res.push("她叫喵喵,");
res.push("她时而可爱,时而认真,");
res.push("她那天真的笑声可以让人忘掉一切烦恼。");
console.log(res.join(""));

(16)封装cookie的添加,删除,查询方法

cookie是存储在浏览器端的,可以用于存储sessionID,也可以用于自动登陆,记住密码等,但是在浏览器端并没有官方的操作cookie的方法,下面我们来封装一下:

CookieUtil={
    addCookie:function(key,value,options){
        var str=key+"="+escape(value);
        if(options.expires){
           var curr=new Date();   //options.expires的单位是小时
           curr.setTime(curr.getTime()+options.expires*3600*1000);
           options.expires=curr.toGMTString();
        }
        for(var k in options){
   //有可能指定了cookie的path,cookie的domain
           str+=";"+k+"="+options[k];
        }
        document.cookie=str;
    },
    queryCookie:function(key){
      var cookies=document.cookie;
//获得浏览器端存储的cookie,格式是key=value;key=value;key=value
      cookies+=";";
      var start=cookies.indexOf(key);
      if(start<=-1){ return null; }  //说明不存在该cookie
      var end=cookies.indexOf(";",start);
      var value=cookies.slice(start+key.length+1,end);
      return unescape(value);
    },
    deleteCookie:function(key){
      var value=CookieUtil.queryCookie(key);
      if(value===null){return false;}
      CookieUtil.addCookie(key,value,{expires:0});
//把过期时间设置为0,浏览器会马上自动帮我们删除cookie
    }
}

(17)事件委托机制

事件委托指的是,不再事件的发生地设立监听函数,而是在事件发生地的父元素或者祖先元素设置监听器函数,这样可以大大提高性能,因为可以减少绑定事件的元素,比如:

<ul>
<li></li>
<li></li>
<li></li>
</ul>

要给li元素绑定click事件,使用事件委托机制的话,就只需要给ul绑定click事件就行了,这样就不需要给每个li'绑定click事件,减小内存占用,提高效率,有兴趣的童鞋可以去看看jQuery的live,bind,on,delegate函数的区别,这几个函数就采用了事件委托机制。


三、其他部分


(1)http状态码

http状态码是表示服务器对请求的响应状态,主要分为以下几个部分

1**:这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束

2**:表示请求成功,

3**:表示重定向

4**:表示客户端错误

5**:表示服务器端错误

100(continue),客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收

200(OK),表示请求成功,请求所希望的响应头或数据体将随此响应返回。

202(Accepted),服务器已接受请求,但尚未处理。

204(No-Content),服务器成功处理了请求,但不需要返回任何实体内容

205(Reset-Content),服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单,以便用户能够轻松地开始另一次输入。

206(Partial-Content),服务器已经成功处理了部分 GET 请求。

301(Moved-Permanently),永久性重定向

302(Moved-Temporarily),暂时性重定向

304(Not-Modified),浏览器端缓存的资源依然有效

400(Bad-Reques),请求有误,当前请求无法被服务器理解。

401(Unauthorized),当前请求需要用户验证。

403(Forbidden),服务器已经理解请求,但是拒绝执行它。

404(Not-Found),请求的资源没有被找到

500(Interval Server Error),服务器内部错误

502(Bad GateWay),网关出错

503(Service Unavailable),由于临时的服务器维护或者过载,服务器当前无法处理请求。

504(Gateway Timeout),作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。

(2)xss,csrf的概念以及防范方法

大公司如bat在面试的时候,web安全问题是必问的问题,所以一定要懂,要彻底理解xss和csrf的概念和防范方式,最好在项目中有用到对这两种攻击的防范,这样会给你的面试加很多分。由xss和csrf涉及的东西比较多,我就不具体给出了,详情请看XSS攻击及防御CSRF攻击

(3)CommonJs,AMD,CMD规范

CMD是国内玉伯大神在开发SeaJS的时候提出来的,属于CommonJS的一种规范,此外还有AMD,其对于的框架是RequireJS

1、二者都是异步模块定义(Asynchronuous Module Definition)的一个实现; 2、CMD和AMD都是CommonJS的一种规范的实现定义,RequireJS和SeaJS是对应的实践;

3、CMD和AMD的区别:CMD相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;而AMD则相反,定义模块的时候需要制定依赖模块,并以形参的方式引入factory中。 区别看下边例子:

//AMD方式定义模块
define(['dep1','dep2'],
function(dep1,dep2){
     //内部只能使用制定的模块
      return function(){};
});
//CMD
define(function(require,exports,module){
   //此处如果需要某XX模块,可以引入
   var xx=require('XX');
});

4、JavaScript语言是弱结构性的,通过CommonJS定义一些规范,CMD和AMD得定义模块的方式对代码进行管理,使得更易维护;此外,NodeJS的诞生,对模块的规范定义,和包(npm)的概念的引入,让JS管理不再困难,一个字,爽爆了

(4)谈谈对前端模块化的理解

前端模块话就是把复杂的文件分成一个个独立的模块,比如js文件,分成独立的模块之后有利于代码的重用和维护,但是这样又会引来模块与模块之间的依赖问题,所以就有了CommonJS、AMD、CMD规范,最后出现了webpack,webpack就是前端模块话的一种解决方案,基本上大公司都会使用webpack

(5)优雅降级和渐进增强

优雅降级指的是一开始就构建功能完好的网站,然后在慢慢兼容低版本的浏览器,使得各个浏览器之间的差异不要太大。

渐进增强是指在基本功能得到满足的情况下,对支持新特性的浏览器使用新特性,带给用户更换的体验。

优雅降级和渐进增强的出发点不同,前者是慢慢向下兼容,是向后看,后着是慢慢向上,增强功能,是向前看。

(6)前端优化(提高网页的加载速度)

1、使用css sprites,可以有效的减少http请求数

2、使用缓存

3、压缩js,css文件,减小文件体积

4、使用cdn,减小服务器负担

5、懒加载图片

6、预加载css,js文件

7、避免dom结构的深层次嵌套

8、给DOM元素添加样式时,把样式放到类中,直接给元素添加类,减少重构,回流


目录
相关文章
|
11天前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
42 1
|
2月前
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
3月前
|
存储 XML 移动开发
前端大厂面试真题
前端大厂面试真题
|
22天前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
3月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
【8月更文挑战第18天】
49 2
|
3月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
37 0
|
3月前
|
存储 前端开发 JavaScript
44 个 React 前端面试问题
44 个 React 前端面试问题
|
3月前
|
存储 JavaScript 前端开发
|
3月前
|
Web App开发 存储 缓存
|
3月前
|
前端开发 应用服务中间件 API
"揭秘!面试官必问:你是如何巧妙绕过跨域难题的?前端代理VS服务器端CORS,哪个才是你的秘密武器?"
【8月更文挑战第21天】在软件开发中,尤其前后端分离架构下,跨域资源共享(CORS)是常见的挑战。主要解决方案有两种:一是服务器端配置CORS策略,通过设置响应头控制跨域访问权限,无需改动前端代码,增强安全性;二是前端代理转发,如使用Nginx或Webpack DevServer在开发环境中转发请求绕过同源策略,简化开发流程但不适用于生产环境。生产环境下应采用服务器端CORS策略以确保安全稳定。
46 0