前端⾯试题(2020-2021)第⼀组
⼀,前端解决跨域问题(常⽤)
1,后端设置cors允许跨域,⼀般指定ip,也可以允许全部
2,jsonp,利⽤浏览器对script加载完⾃动执⾏的特新来实现的,需要客户端和服务器端两端的同时配合,因此需要特别处理的接⼝可以使⽤,⼀般传统的后台接⼝不会采⽤这种⽅式进⾏跨域。
3,Nginx反向代理,⼀般利⽤vue-cli全家桶,开发时在fig.js中设置接⼝在同⼀个后端域名和端⼝,正式服务则使⽤Nginx确保在统⼀域名下。
⼆,常见web安全及防护
防护:
1,对⽤户输⼊内容进⾏限制和校验
2,对所有关键数据进⾏加密
3,接⼝提交⽅式严格规范,数据提交不使⽤get
攻击⽅式:
sql注⼊,xss(恶意注⼊js和⽹页元素),csrf(代替⽤户完成交互并访问危险⽹站)
三,js垃圾回收机制
js的垃圾回收机制是⾃动执⾏的,且不可发现的。垃圾回收的对象分为:全局变量和局部变量(函数内变量)。全局变量只有在页⾯被关闭时才被回收,局部变量在所属函数调⽤结束后回收。回收⽅式分为两类⼀种是标记清除,⼀种是引⽤计数。
四,前端性能优化
1,尽量压缩css和js⽂件⼤⼩
2,采⽤less或者sass
3,图⽚懒加载
4,精灵图和雪碧图
5,接⼝尽可能做到重复使⽤
6,数据请求异步操作,防⽌页⾯卡顿
五,闭包理解
闭包就是⼀个函数,两个函数嵌套在⼀起,内部函数就是闭包。形成闭包的条件:内部函数需要通过return返回出来。
function f1(){
function f2(){
alert("我是js闭包!");
}
return f2;
}
var f=f1();
f();//弹出:我是js闭包!
内部函数可以调⽤外部函数的参数。
⽤得⾮常多,包括异步请求,vue的函数嵌套,⾮常常见,有时候写起来,根本想不起来闭包啥的。
六,cookie和session的区别
1,存储位置有区分,cookie存在浏览器缓存中,session存储在服务器上
2,存储⼤⼩和数量 cookie⼩于session
3,保密性 cookie对游览器和⽤户可见 session存在服务器上,保密性更佳
4,服务器压⼒ session对服务器压⼒更⼤
重点
在实际开发过程中,cookie和session都很少使⽤,更为常⽤的是token,它⽐上两个优势更⼤,更好⽤,安全性⾼,可扩展性强,多平台跨域,⽆状态。可实现,单点登录和多点登录等功能。
重点
请不要混淆session和sessionStorage,前者是⾝份验证(类似于令牌),后者是⼀种存储⽅式,数据保存在浏览器缓存中(localStorage存储在本地需要⼿动删除才会消失),关闭浏览器和标签页就会消失。
重点
有种说法是cookies和localStorage和sessionStorage是同⼀类,都是储存⽅式,只是⼤⼩,保存位置,保存时间不⼀样
⼤⼩ cookies<sessionStorage=localStorage
保存位置 本地
时间 cookies有指定时间 sessionStorage关闭页⾯ localStorage不主动清除⼀直存在
七,那些操作会造成内存泄漏
1,什么是内存泄漏
看上⾯的垃圾回收机制,当有变量和对象,应该被回收,⽽没有被回收时,⼀直占⽤和停留在堆内存中,这就产⽣内存泄漏。
2,内存泄漏影响
内存泄漏会导致内存被占⽤过多⽆法释放,从⽽导致系统内存分配不⾜,造成了内存溢出从⽽导致应⽤Crash(浏览器崩溃)。
3,前端造成内存泄漏的操作
1,闭包
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很⼤,过多的使⽤闭包,不及时释放,会导致内存泄漏。
2,意外全局
函数中定义参数,var 定义,会成为全局变量,建议使⽤es6的let
3,定时器
4,⽣命周期中使⽤全局函数,未释放
5,echarts
6,keep-alive组件
其实在vue中⼀般这些是不会造成内存泄漏,只有程序猿⾃⼰写的bug才会导致,还有对于现在电脑来说,⼀些内存泄漏并不影响。
⼋,重构的理解
重构不是重写项⽬重构不是重写项⽬重构不是重写项⽬
重构是⼀种对软件内部结构的改善,包括去除重复、简化复杂逻辑和澄清模糊的代码,甚⾄可能是变更⼀个参数名。
重构和重写之间的差异在于: 重构是在标准化流程和⽅法的指导下,给正在跑的车换轮⼦,乘客(业务⽅)不受影响。重写是推倒重来,⽐较理想的结果是你把新车造好了让乘客跳过来,但真能做到的团队不多,需要很⾼的⼯程管理能⼒。
九,常见浏览器内核
1,edge的edgeHTML
2,⽕狐的Gecko
3,Safari的webKit
4,Chrome的Blink
⼗,DOM创建,添加,移动,复制,查,删除节点,
1,创建 atElement(‘a’) //创建a元素节点 多⽤于下载操作 页⾯显⽰ <a> </a>
2,添加节点 appendChild()
let ul = ElementById('ul');
let li = atElement('li');
ul.appdenChild(li);
⼀般⽤于对页⾯添加⽂本列表项啥的。
3,删除节点 removeChild()
var ul = ElementById("myList");//获得ul
var lis = ul.getElementsByTagName("li")//获取ul中所有li的集合
4,查节点(常⽤)
5,复制节点 cloneNode()
1var ul = ElementById("myList");//获得ul
2var deepList = ul.cloneNode(true);//深复制
3var shallowList = ul.cloneNode(false);//浅复制
⼗⼀,事件模型的三个阶段
⼀个事件的处理过程主要有三个阶段:捕获,⽬标,冒泡;
(1)捕获: 当我们在 DOM 树的某个节点发⽣了⼀些操作(例如单击、⿏标移动上去),就会有⼀个事件发射过去。这个事件从Window 发出,不断经过下级节点直到触发的⽬标节点。在到达⽬标节点之前的过程,就是捕获阶段(Capture Phase)。( 所有经过的节点,都会触发这个事件。捕获阶段的任务就是建⽴这个事件传递路线,以便后⾯冒泡阶段顺着这条路线返回 Window。 )
(2)⽬标阶段:当事件不断的传递直到⽬标节点的时候 ,最终在⽬标节点上触发这个事件,就是⽬标阶段。
(3) 冒泡阶段: 事件冒泡即事件开始时,由最具体的元素接收(也就是事件发⽣所在的节点),然后逐级传播到较为不具体的节点(我们平时⽤的事件绑定就是利⽤的事件冒泡的原理)
事件委托就是利⽤事件冒泡,只指定⼀个事件处理程序,就可以管理某⼀类型的所有事件
这⾥得提到阻⽌事件冒泡
⽅法⼀:event.stopPropagation( )
//为所有button元素绑定click事件
$(":button").click(function(event){
alert("button-click");
// 阻⽌事件冒泡到DOM树上
event.stopPropagation();// 只执⾏button的click,如果注释掉该⾏,将执⾏button、p和div的click (同类型的事件)
});
⽅法⼆:event.target
$(document).ready(function(){
$('#switcher').click(function(event){
if(event.target==this){//判断是否是当前绑定事件的元素元素触发的该事件
$('#switcher .button').toggleClass('hidden');
}
})
})
还得提到js的事件绑定
这个就是⾮常基础的东西
1,原⽣函数
<input onclick="alert('谢谢⽀持')" type="button" value="点击我,弹出警告框"/>
2,⾃定义函数
<input onclick="myAlert()" type="button" value="点击我,弹出警告框"/>
<script type="text/javascript">
function myAlert(){
alert("谢谢⽀持");
}
</script>
3,js代码绑定
<input id="demo" type="button" value="点击我,显⽰ type 属性"/>
<script type="text/javascript">
Attribute("type"));// this 指当前发⽣事件的HTML元素,这⾥是<div>标签
}
</script>
web前端开发笔试题库4,事件监听(⽤的不多)
绑定事件的另⼀种⽅法是⽤ addEventListener() 或 attachEvent() 来绑定事件监听函数。
⼗⼆,css盒⼦模型
标准的盒⼦模型 元素宽度 = width(内容宽)+ padding(内边距)+border(边框)+margin(外边距)
低版本ie 元素宽度 = width(内容+内边距+边框)+margin(外边距)
⼗三,js继承
实现继承⾸先需要⼀个⽗类,在js中实际上是没有类的概念,在es6中class虽然很像类,但实际上只是es5上语法糖⽽已1,原型链继承(常⽤,如引⽤⼯具类函数)
function Woman(){
}
Woman.prototype=new People();
Woman.prototype.name ='haixia';
let womanObj =new Woman();
优点:
简单易于实现,⽗类的新增的实例与属性⼦类都能访问
缺点:
可以在⼦类中增加实例属性,如果要新增加原型属性和⽅法需要在new ⽗类构造函数的后⾯
⽆法实现多继承
创建⼦类实例时,不能向⽗类构造函数中传参数
2,借⽤构造函数继承(伪造对象、经典继承)
复制⽗类的实例属性给⼦类
function Woman(name){
//继承了People
People.call(this);//People.call(this,'wangxiaoxia');
this.name = name ||'renbo'
}
let womanObj =new Woman();
优点:
解决了⼦类构造函数向⽗类构造函数中传递参数
可以实现多继承(call或者apply多个⽗类)
缺点:
⽅法都在构造函数中定义,⽆法复⽤
不能继承原型属性/⽅法,只能继承⽗类的实例属性和⽅法3,实例继承(原型式继承)
4,组合式继承
function People(name,age){
this.name = name ||'wangxiao'
this.age = age ||27
}
People.prototype.eat=function(){
return this.name +this.age +'eat sleep'
}
function Woman(name,age){
People.call(this,name,age)
}
Woman.prototype =new People();
structor = Woman;
let wonmanObj =new Woman(ren,27);
wonmanObj.eat();
5,寄⽣组合继承
/⽗类
function People(name,age){
this.name = name ||'wangxiao'
this.age = age ||27
}
//⽗类⽅法
People.prototype.eat=function(){
return this.name +this.age +'eat sleep'
}
/
/⼦类
function Woman(name,age){
//继承⽗类属性
People.call(this,name,age)
}
//继承⽗类⽅法
(function(){
// 创建空类
let Super=function(){};
Super.prototype = People.prototype;
//⽗类的实例作为⼦类的原型
Woman.prototype =new Super();
})();
//修复构造函数指向问题
structor = Woman;
let womanObj =new Woman();
⼗四,浏览器访问页⾯发⽣什么
1、DNS查询
2、TCP链接
3、发送HTTP请求
4、Server处理HTTP请求并返回HTTP报⽂
5、浏览器解析并render页⾯
6、HTTP连接断开
⼗五,清除浮动
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论