前端面试题总结
HTML 指的是超文本标记语言 (Hyper Text Markup Language)
1.HTML5中的语义化元素
语义学(源自古希腊)可定义为对语言意义的研究。
语义元素:是拥有语义的元素,可以清楚的向浏览器和开发者描述其意义。
非语义元素的例子: <div>和<span>----无法提供关于其内容的信息。
语义元素的例子:<form>,<table>,<img>---清晰的定义其内容
优点:
- 语义化可以让计算机能够快读的读懂内容,高效的处理信息,可以对搜索引擎更友好
- 便于与他人的协作,他人通过读代码就可以理解你网页标签的意义
- 去掉或者丢失样式的时候能够让页面呈现出清晰的结构
- 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重
- 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义方式来渲染网页
- 便于团队开发和维护,语义化更具有可读性,遵循这个标准,减少差异化
2.介绍HTML5的新特性
1.新的DOCTYPE声明<!DOCTYPE html>
2.新的语义元素 <header> <footer> <nav>
3.新的表单控件
4.强大的多媒体支持 <video> <audio>
5.canvas 和svg绘图
<canvas>绘图时,canvas标签只是一个图形容器它本身是没有绘图能力的,必须使用脚本来绘制图形(所有的绘制工作必须在javascript内部完成)
SVG是指可伸缩的矢量图形
6.拖放api
7.定位用户的位置
HTML5 geolocation API 用于获得用户的地理位置(鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的)
8.在客户端存储数据
HTML5 提供了两种在客户端存储数据的新方法:
localStorage (本地存储) - 没有时间限制的数据存储。
1.一般情况下是永久保存的,也就是说只要采用localstorage保存信息,数据便会一直存储在用户的客户端中,
即使用户关闭当前web浏览器后重新启动,数据仍然存在,直到用户或者程序明确制定删除,数据的生命周期才会结束。
2.存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
sessionStorage(会话存储) - 针对一个 session 的数据存储 。
1.sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除。
2.存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
sessionStorage和localstorage都是Storage类型的一个对象。
WebStorage提供了一些方法,数据操作比cookie方便
setItem (key, value) —— 保存数据,以键值对的方式储存信息。
getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。
removeItem (key) —— 删除单个数据,根据键值移除对应的信息。
clear () —— 删除所有的数据
key (index) —— 获取某个索引的key
sessionStorage、localStorage和cookie的区别
1)相同点是都是保存在浏览器端、且同源的
2)cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
3)存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
4)数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
5)作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
6)web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
7)web Storage的api接口使用更方便
这部分参考链接:https://blog.csdn.net/weixin_42614080/article/details/90706499
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3.如何解决ajax无法后退的问题?
- html5里引入了新的API,即:history.pushState, history.replaceState
- 可以通过pushState和replaceSate接口浏览器历史,并且改变当前页面的URL
- HTML5增加了一个事件window.onpopstate,当用户点击浏览器的‘后退’和‘前进’按钮时就会触发这个事件。
4.websocket和ajax轮询
- websocket是html5中提出的新的协议,可以实现客户端与服务器的通信,实现服务器的推送功能
- 优点是,只要简历一次连接,就可以连续不断的得到服务器推送消息,节省带宽和服务器端的压力。
- ajax轮询模拟常连接就是每隔一段时间(0.5s)就向服务器发起ajax请求,查询服务器是否有数据更新
- 缺点就是,每次都要建立HTTP连接,即使需要传输的数据非常少,浪费带宽
本知识点参考链接:https://blog.csdn.net/baidu_38990811/article/details/79172163
5.web worker和websocket
- 通过worker = new worker(url)加载一个js文件来创建一个worker,同时返回一个worker实例
- 通过worker.postMessage(data)方法来向worker发送数据。
- 绑定worker.onmessage方法来接收worder发送过来的数据
- 可以使用worker.terminate()来终止一个worder的执行。
6.Doctype作用?严格模式与混杂模式如果区分?意义?
- <!DOCTYPE>声明位于文档的最前面,处于标签之前。告知浏览器以何种模式来渲染文档
- 严格模式的排版和js运作模式是 以该浏览器支持的最高标准运行
- 在混杂模式中,页面已宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作
- DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现
7.Doctype多少种文档类型?
- 该标签可声明三种DTD类型,分别表示严格版本、过渡版本以及基于框架的HTML文档
- HTML4.01规定了三种文档类型:Strict, Transitional以及Frameset
- XHTML 1.0规定了三种XML文档类型:Strict, Transitional以及Franmeset
- Standards(标准)模式(也就是严格呈现模式)用于呈现遵循最新标签的网页,而Quirks(包容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页
8.HTML与XHTML,有什么区别?
- 所有的标签必须要有一个相应的结束标签
- 所有标签的元素和属性的名字都必须使用小写
- 所有的XML标记都必须合理嵌套
- 所有的属性必须引号“”括起来
- 把所有的<和&特殊符号用编码表示
- 给所有属性赋一个值
- 不要在注释内容使用'--'
- 图片必须要有说明文字
CSS
1.content-box和border-box,为什么看起来content-box更合理,但还是经常使用border-box?
- content-box是W3C的标准盒模型 元素宽度+padding+border
- border-box 是ie的怪异盒模型,他的元素宽度等于内容宽度 内容宽度包含了padding和border
- 比如有时候在元素基础上添加内边距padding或border会将布局撑破 但是使用border-box就可以轻松完成
2.实现三个DIV等分排在一行(考察border-box)
flex
取值为一个非负数字,则该数字为 flex-grow
值,flex-shrink
取 1,flex-basis
取 0%,如下是等同的
3.实现两栏布局有哪些方法
*{
margin: 0;
padding:0;
} html,body{ height: 100%; } #left{ width: 300px; height: 100%; float: left; } #right{ height: 100%; margin-left: 300px; //使用margin 值为左边盒子的宽度 background-color: #eee; }
*{ margin: 0; padding: 0; } html,body{height: 100%;} #left{ width: 300px; height: 100%; float: left; } #right{ height: 100%; overflow: hidden; //使right元素成为BFC backrgound-color: #eee; }
- float的值不为none
- position的值不为static 或者 relative
- display的值为table-cell,table-caption,inline-block,flex,或者inline-flex其中一个
- overflow的值不为visible
4.flex属性值是多少?
- flex属性是flex-grow,flex-shrink 和 flex-basis的简写
- flex-grow属性定义项目的放大比例,默认为0
- flex-shrink属性定义了项目的缩小比例,默认为1
- flex-basis属性定义了项目的固定空间,默认auto
5.怎么实现一个DIV左上角到右下角的移动,有哪些方法?怎么实现?
- 改变left值为window宽度-div宽度 top值为window高度=div高度
- jquery的animate方法
- css3的transition
6.垂直居中
- 单行行内元素
- 可以设置padding-top,padding-bottom
- 将height和line-height设为相等
- 多行行内元素块级元素
- 可以将元素转为tabel样式,再设置vertical-align:middle;
- 使用flex布局
- 已知高度绝对定位负边距
- 未知高度transform:translateY(-50%);
- flex布局
display: flex; justify-content: center; aligin-items: center;
7.rem 和 em的区别?
em相对于使用他们的元素的字体大小,rem相对于根元素
rem:当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的字体大小。 根元素字体大小乘以你 rem 值。
em:有一个比较普遍的误解,认为 em 单位是相对于父元素的字体大小。 事实上,根据W3标准 ,它们是相对于使用em单位的元素的字体大小。
父元素的字体大小可以影响 em 值,但这种情况的发生,纯粹是因为继承。
8.清除浮动
9.position的值, relative和absolute分别是相对于谁进行定位的?
- relative:相对定位,相对于自己本身在正常文档流中的位置进行定位。
- absolute:生成绝对定位,相对于最近一级定位不为static的父元素进行定位。
- fixed: (老版本IE不支持)生成绝对定位,相对于浏览器窗口或者frame进行定位。
- static:默认值,没有定位,元素出现在正常的文档流中。
- sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。
-
position: sticky,基于用户的滚动位置来定位。
粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。
它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。
10.CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?
- 选择符:
- id选择器(#myId)
- 类选择器(.myClassName)
- 标签选择器(div,p,h1)
- 相邻选择器(h1 + p)
- 子选择器(ul > li)
- 后代选择器(li a)
- 通配符选择器(*)
- 属性选择器(button[disabled="true"])
- 伪类选择器(a:hover,li:nth-child)
- 优先级:
- !important > 行内样式(比重1000) > id(比重100) > class/属性(比重10) > tag / 伪类(比重1);
- 伪类和伪元素区别:
- a:hover,li:nth-child
- 伪元素:li:before、:after,:first-letter,:first-line,:selection
11.介绍sass
定义变量css嵌套,允许在代码中使用算式,支持if判断for循环
Sass(Syntactically Awesome StyleSheets)是css的一个扩展开发工具,它允许你使用变量、条件语句等,使开发更简单可维护。
可以用 & 代表嵌套规则外层的父选择器。
.fatherDiv { width:100px; &.pBox { //&代表 .fatherDiv color: red; } }
12.transition 和 margin的百分比根据什么计算?
1.margin相对于参照物
2.transition是相对于自身,若设置宽度变成200%,则是变成自身100px的200%。
看个例子:把鼠标指针放到 div 元素上,其宽度会从 100px 逐渐变为 300px:
13.实现一个秒针绕一点转动的效果
1.CSS @keyframes 规则
2.CSS animation 属性
animation: move 60s infinite steps(60); /*设置旋转的中心点为中间底部*/ transform-origin: center bottom; /*旋转从0度到360度*/ @keyframes move { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
14.display:none和visibility:hidden的区别?
- display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在。
- visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间。
15.CSS中link 和@import的区别是?
- link属于HTML标签,而@import是CSS提供的;
- 页面被加载的时,link会同时被加载,而@import被引用的CSS会等到引用它的CSS文件被加载完再加载;
- import只在IE5以上才能识别,而link是HTML标签,无兼容问题;
- link方式的样式的权重 高于@import的权重.
16.对BFC规范的理解?
- BFC,块级格式化上下文,一个创建了新的BFC的盒子是独立布局的,盒子里面的子元素的样式不会影响到外面的元素。在同一个BFC中的两个毗邻的块级盒在垂直方向(和布局方向有关系)的margin会发生折叠。
- (W3C CSS 2.1 规范中的一个概念,它决定了元素如何对其内容进行布局,以及与其他元素的关系和相互作用。
JS
1.介绍一下闭包和闭包常用场景?
- 使用闭包主要为了设计私有的方法和变量,闭包的优点是可以避免变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念。
- 闭包有三个特性:
- 函数嵌套函数
- 嵌套的子函数引用了父函数的变量,并且在父函数中把子函数return出去,这样外部就可以访问父函数中的变量了。
- 参数和变量不会被垃圾回收机制回收
- 闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包常见方式,就是在一个函数的内部创建另一个函数
- 应用场景,设置私有变量的方法
- 不适用场景:返回闭包的函数是个非常大的函数
- 闭包的缺点就是常驻内存,会增大内存使用量,使用不当会造成内存泄漏
f1是f2的父函数,f2被赋给了一个全局变量,f2始终存在内存中,f2的存在依赖f1,因此f1也始终存在内存中,不会在调用结束后,被垃圾回收机制回收.
看一下什么是函数柯里化:参考链接:https://www.jianshu.com/p/2975c25e4d71
2.为什么会出现闭包这种东西?解决了什么问题?
受javascript链式作用域链的影响,父级变量中无法访问到子级的变量值
闭包是用来解决全局变量私有化的,也可以说成局部变量全局化。
3.介绍一下你所了解的作用域链,作用域链的尽头是什么?为什么?
- 每一个函数都有一个作用域,比如创建了一个函数,函数里面又包含了一个函数,那么现在有三个作用域(两个函数作用域+全局作用域),这样就形成了一个作用域链
- 作用域的特点就是,先在自己的变量范围中查找,如果找不到,就会沿着作用域链网上找。
- 作用域链的尽头就是全局作用域。
4.ajax建立的过程是怎样的,主要用到哪些状态码?
$.ajax({ type:"GET", // get或者post请求 url:”xxxxxxxx“, dataType:"json", // 预期服务器返回数据的类型 success:function(data){ // 请求成功的回调函数 if(data.success){ //ToDo }else{ //ToDO } }, error:function(jqXHR){ // 请求失败的回调函数 //ToDo } });
- 创建XMLHttpRequest对象,也就是创建一个异步调用对象
- 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
- 设置响应HTTP请求状态变化函数
- 发送HTTP请求
- 获取异步调用返回的数据
- 使用javascript和DOM实现局部刷新
var xmlHttp = new XMLHttpRequest(); xmlHttp.open('GET','demo.php','true'); xmlHttp.send() xmlHttp.onreadystatechange = function(){ if(xmlHttp.readyState === 4 & xmlHttp.status === 200){ } }
5.使用promise封装
function getJSON(url){ return new Promise(function(resolve, reject){ var XHR = new XMLHttpRequest(); XHR.open('GET', url,true); XHR.send(); XHR.onreadystatechange = function() { if(XHR.readerSate == 4){ if(XHR.status == 200){ try { var response = JSON.parse(XHR.responseText); resilve(response); } cath(e) { reject(e); } }else{ reject(new Error(XHR.statusText)); } } } }) } getJSON(url).then(res => console.log(res));
- 常用状态码status
- 404没找到页面
- 403禁止访问
- 500内部服务器出错
- 200正常
- 304被又被修改(not modified)(服务器返回304状态,表示源文件没有被修改)
- 说说你还知道的其他状态码,状态码的存在解决了什么问题?
- 302/307 临时重定向
- 301 永久重定向
- 借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了什么错误
6.事件委托
- 利用冒泡原理,把时间加到父级上,触发执行效果
- 可以大量节省内存占用,减少事件注册
- 可以方便地动态添加和修改元素,不需要因为元素的改动而修改时间绑定
var ul = document.querySelector('ul'); var list = document.querySelectorAll('ul li'); ul.addEventListener('click', function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElemnt; for(var i = 0, len = list.length; i < len; i++){ if(list[i] == target){ alert(i + "----" + target.innerHTML); } } });
7.javascript的内存回收机制?
js具有自动回收机制,垃圾收集器会按照固定的时间间隔周期性的执行
- 垃圾回收器会每隔一段时间找出那些不再使用的内存,然后为其释放内存
- 一般使用标记清除方法 当变量进入环境标记为进入环境,离开环境标记为离开环境
- 还有引用计数方法
两种方式:
(1)标记清除
原理:当变量进入环境时,将这个变量定义为“进入环境”,将变量离开环境时,将其标记为“离开环境”,标记“离开环境”的就回收内存。
工作流程:
- 垃圾回收器。在运行的时候给存储在内存中的所有变量都加上标记。
- 去掉环境中的变量以及被环境中的变量引用的变量(闭包)的标记。
- 此时仍有标记的变量视为即将要删除的变量
- 垃圾回收器完成内存清除的工作,销毁那些带标记的值并回收他们所占的内存空间。
(2)引用计数
工作原理:跟踪记录每个值被引用的次数
工作流程:
- 声明一个变量并将一个引用类型值赋值给这个变量,这个引用类型值的引用次数就是1
- 同一个引用类型值又被赋值给另一个变量,这个引用类型值的引用次数就加1
- 当包含这个引用类型值的变量又取得了另一个值,这个引用类型值的引用次数就会减1
- 当引用次数变为0时,说明没法访问这个值了。
- 当垃圾回收器下一次运行时就会释放引用次数为0的值所占的内存空间。
引用计数的问题:循环引用 。循环引用指的是对象A中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。请看下面这个例子:
在这个例子中,objectA 和 objectB 通过各自的属性相互引用;也就是说,这两个对象的引用次数都是 2。
在采用标记清除策略的实现中,由于函数执行之后,这两个对象都离开了作用域,因此这种相互引用不是个问题。但在采用引用计数策略的实现中,当函数执行完毕后,objectA 和 objectB 还将继续存在,因为它们的引用次数永远不会是 0。
堆栈
- stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放
- 基本数据类型存放在栈中
- 引用类型 存放在堆内存中,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据
8.函数防抖和函数节流?
1.首先看看防抖的实现:
在这里我们需要修复两个问题:
- this 指向
- event 对象
参考链接:JavaScript专题之跟着underscore学防抖
参考链接:JavaScript专题之跟着 underscore 学节流
9.javascript中的this是什么,有什么用,指向上面?
- 全局代码中的this是指向全局对象
- 作为对象的方法调用时指向调用这个函数的对象
- 作为构造函数指向创建的对象
- 使用apply和call设置this
10.判断数组有哪些方法?
- a instanceof Array 判断一个对象是否是构造函数Array的实例
- a.constructor ===Array 实例的constructor属性指向构造函数
- Array.isArray(a) 这个是数组自带的方法
- Object.protype.toString.call(a) === [Object Array] -->这个方法是100%准确的方法
11.严格模式的特性?
- 对javascript的语法和行为,都做了一些改变
- 全局变量必须显式的声明。
- 对象不能有重名的属性
- 函数必须声明在顶层
- 消除js语法的一些不合理,不严谨之处,减少一些怪异行为
- 消除代码运行的一些不安全之处,保证代码运行的安全
- 提高编译效率,增加运行速度
- 为未来新版本的js做好铺垫
12.js的原型链,如何实现继承?
function Foo(){}; Foo.prototype.z = 3; var obj = new Foo(); obj.x = 1; obj.y = 2; obj.x //1 obj.y //2 obj.z //3 obj本身没有z属性,z是原型上的属性
13.图片懒加载
当页面滚动的时间被触发->执行加载图片操作->判断图片是否在可视区域内->在,则动态将data-src的值赋予该图片。
为啥要对图片使用懒加载?我们首先来聊聊这个问题,对于页面来说架子啊速度影响着最大的就是图片,一张普通的图片可以达到4-5M的大小,而代码压缩也就只有几十KB。
当页面图片过多的时候,页面加载速度很缓慢,一个页面加载几秒没有完成,用户体验不好,会丧失很多用户的。
所以对于图片过多的页面,可以为了加速页面加载速度,很多时候我们需要将页面内未出现的可视区域内的图片先不加载,等到滚动到可视区的时候录再去加载。这样子对于页面加载性能上会有很大的提升,也就提高了用户体验。
关于图片的懒加载,网上有一篇文章,可以收藏参考:https://www.cnblogs.com/chengxs/p/11136422.html
14.webpack常用到哪些功能?
- 设置入口
- 设置输出目录
- 设置loader
- extract-text-webpack-plugin将css从js代码中抽出并合并
- 处理图片文字等功能
- 解析jsx解析bable
详细可以参考链接:https://www.cnblogs.com/laneyfu/p/6131441.html
15.函数组合继承
原型继承,构造函数继承,call apply继承
var super = function(name){ this.name = name; } super.prototype.func1 = function() {console.log('func1')} var sub = function(name, age){ super.call(this, name); this.age = age; } sub.prototype = new super()'
16.对作用域链的理解
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链额变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的
17.js垃圾回收方法
标记清除(mark and sweep)
- 这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
- 垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
引用计数(reference counting)
- 在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
- 在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的, 也就是说只要涉及BOM及DOM就会出现循环引用问题。
18.js继承方式及其优缺点
原型链继承的缺点
- 一是字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数
借用构造函数(类试继承)
- 借用构造函数虽然解决了刚才两种问题,但是没有原型,则复用无从谈起,需要原型链+借用构造函数的模式,这种模式成为组合继承
组合式继承
- 组合式继承是比较常用的一种继承方法,其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承,这样,即通过在原型上定义方法实现了函数复用,有保证每个实例都有它自己的属性
ES6
1.let和const的区别?
- let声明的变量可以改变,值和类型都可以改变,没有限制
- const声明的变量不得改变值
2.平时用了es6的哪些知识点,和es5有什么不同?
- let,const,箭头函数,字符串模板,class类,模块化,promise
- ES5 reuqire,react,createclass
3.介绍promise
- 就是一个对象,用来传递异步操作的消息。有三种状态:pending(进行中),resolved(已完成)和rejected(失败)
- 有了promise对象,就可以将异步操作以同步操作的流程表示出来,避免了层层嵌套的回调函数
前端框架
模块化
1.使用模块化加载时,模块记载的顺序是怎么样的,如果不知道,根据已有的知识,加载顺序是怎么样的
- commonjs 同步 循序执行
- AMD 提前加载,不管是否调用模块,先解析所有模块require速度快 有可能浪费资源
- CMD提前加载,在正真需要使用(依赖)模块时才解析该模块
- seajs按需解析,性能比AMD差
框架问题
1.什么是MVVM,和MVC有什么区别,原理是什么?
- mvc的界面和逻辑关联紧密,数据直接从数据库读取,必须通过controller来承上启下,通信都是单向的。
- mvvm的view 和 viewModel可以互相通信,界面数据从viewmodel中获取。
- 利用Object.defineProperty(),该方法有get、set两个属性方法,从而获取对象属性的值,给对象属性重新赋值。
- 参考链接:https://blog.csdn.net/weixin_34163741/article/details/88129568
2.父子组件通信
- vue:父组件是通过props属性给子组件通信,在子组件里面emit,在父组件监听
- react:props传递 父给子传一个回调函数,将数据传给父亲处理
3.兄弟组件怎么通信的?
- vuex 建立一个vue的实例,emit触发时间 on监听时间
- redux 子A ->父->子B
4.生命周期有哪些,怎么用?
- beforeCreated: el 和 data并未初始化
- created: 完成了 data数据的初始化,el没有
- beforeMount:完成了el 和 data初始化
- mounted:完成挂载,updated,destroyed
浏览器
1.跨域通信有哪些解决方案?
- JSONP:
- 由于同源策略的限制,XMLHttpRequest只允许请求当前资源(域名、协议、端口)的资源,script标签没有同源限制,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
- 通过动态<script>元素使用,使用时为src制定一个跨域url。回调函数处理JSON数据
优点:兼容性好,简单易用,支持浏览器与服务器双向通信
缺点:只支持GET请求
var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction"; var script = document.createElement('script'); script.setAttribute('src', url); //load javascript document.getElementsByTagName('head')[0].appendChild(script); //回调函数 function callbackfunction(data){ var html=JSON.stringify(data.RESULTSET); alert(html); }
- CORS:
- 服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Orgin来进行的。如果浏览器检测到响应的设置,就可以允许ajax进行跨域访问。
- 通过设置Access-Control-Allow-Orgin来允许跨域,cors可以用ajax发请求获取数据,但是兼容性没有jsonp好
- 通过修改document.domain来跨子域
- 将子域和主域的doucment.domain设为同一个主域,前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致
- 主域相同的使用document.domain
- 使用window.name来进行跨域使用HTML5中心引进的window.postMessage方法来跨域传送数据
- window对象有个name属性,该属性有个特征:即在一个窗口的生命周期内,窗口载入的所有的页面都是共享一个window.name。每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的
- 还有flash,在服务器上设置代理页面等跨域方式。
2.移动端兼容问题
- IOS移动端click时间300ms的延迟响应
- 一些情况下对非可点击元素如(label,span)监听click时间,ios下不会触发,css增加cursor:poiner就搞定了
3.XML和JSON的区别?
- 数据体积方面:JSON相对于XML来讲,数据的体积小,传递的速度更快些
- 数据交互方面:JSON与js的交互更加方便,更容易解析处理,更好的数据交互
- 数据描述方面:JSON对数据的描述性比XML较差
- 传输速度方面:JSON的速度远远要快于XML
4.渐进增强和优雅降级
- 渐进增强:针对低版本的浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的体验效果
- 优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容
构建工具
1.webpack的理解,和gulp有什么不同?
- webpack是模块打包工具,会分析模块间的依赖关系,然后使用Loaders处理他们,最后生成一个优化并且合并后的静态资源
- gulp是前端自动化工具,能够优化前端工作流程,比如文件合并压缩
2.webpack打包速度很慢, 为什么?怎么解决?
- 模块太多
- webpck可以配置externals来将依赖的库指向全局变量,从而不再打包这个库
3.对webpack的看法
- webpack是一个模块打包工具,可以使用webpack管理你的模块依赖,并编译输出模块们所需要的静态文件。能很好的管理、打包web开发中所用到的HTML、js、css以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。
- webpack两大特色:
- code splitting(可以自动完成)
- loader 可以处理各种类型的静态文件,并且支持串联操作
webpack是以commonJS的形式来书写脚本,但是AMD/CMD的支持也很全面,方便旧项目进行代码迁移
- webpck具有require和browserify的功能,但仍有很多自己的新特性:
- 对 CommonJS、AMD、ES6的语法做了兼容
- 对JS、css、图片等资源文件都支持打包
- 串联式模块化加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对conffeescript、ES6的支持
- 有独立的配置文件webpck.config.js
- 可以将代码切割成不同的chunk,实现按需加载,降低了初始化时间
- 支持sourceUrls和sourceMaps,易于调试
- 具有强大的plugin接口,大多是内部插件,使用起来比较灵活
- webpack使用异步IO并具有多级缓存,在增亮编译上更加快
网络&存储
1.http响应中content-type包含哪些内容?
- 请求中的消息主题是用何种方式解码
- application/x-www-form-urlencoded
- 这是最常见的post提交数据的方式,按照key1=val1&key2=val2的方式进行编码
- application/json
- 告诉服务器端消息主体是序列化后json字符串
-
2.get和post有什么不同?
- get是从服务器上获取数据,post是像服务器传送数据
- get请求可以将查询字符串参数追加到url的末尾;post请求把数据作为请求的主体提交
- get请求数据有大小限制;post没有
- post比get安全性更高
3.cookie和session有什么联系和区别?
- cookie数据存放在客户的浏览器上,session数据放在服务器上
- session比cookie更安全
- 单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie
- 一般用cookie来存储sessionid
4.多页面通信有哪些方案,各有什么不同?
- localstroge在一个标签页里添加、修改、删除时,都会触发一个storage事件,通过另一个标签页里监听storage事件,即可得到localstorge存储的值,实现不同标签页之间的通信。
- setInterval+cookie方式:
-
- 参考链接:https://blog.csdn.net/weixin_46399753/article/details/105211771
5.输入url后到页面展现的全过程?
- 根据域名到DNS中找到IP
- 根据IP建立TCP连接(三次握手)
- 连接建立成功发起http请求
- 服务器响应http请求
- 浏览器解析HTML代码并请求html中的静态资源(js/css)
- 关闭TCP连接(四次挥手)
- 浏览器渲染页面
6.客户端解析渲染页面
构建DOM树->构建渲染树->布局渲染树:计算盒模型位置和大小->绘制渲染树
7.前端性能优化
- 代码层面:避免使用css表达式,避免使用高级选择器,通配选择器
- 缓存利用:缓存ajax,使用CDN,使用外部js和css文件以便缓存
- 添加expires头,服务器配置Etag,减少DNS查找
- 请数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载
- 请求带宽:压缩文件,开始GZIP
- 代码层面的优化:样式放在顶部,脚本放在底部
- 用hash-table来优化查找
- 少用全局变量
- 用innerHTML代替DOM操作,减少DOM操作次数,优化js性能
- 用setTimeout来避免页面是去响应
- 缓存DOM节点查找的结果
- 避免使用css Expression
- 避免全局查询
- 避免使用with(with会创建自己的作用域,会增加作用域链长度)
- 多少变量声明合并
- 避免图片和iframe等的空src,空src会重新加载当前页面,印象速度和效率
- 尽量避免写在HTML标签中写style属性
8.移动端性能优化
- 尽量使用css3动画,开启硬件加速
- 适当使用touch时间代替click时间
- 避免使用css3渐变阴影效果
- 可以用transform: translateZ(0) 来开启硬件加速
- 不滥用float。float在渲染时计算量比较大,尽量减少使用
- 不滥用web字体。web字体需要下载,解析,重绘当前页面
- 合理使用requestAnimationFrame动画代替setTimeout
- css中的属性(css3 transitions、css3 3D transforms、opacity、webGL、video)会触发GUP渲染,耗电
9.分域名请求图片的原因和好处?
- 浏览器的并发请求数目限制是针对同一域名的,超过限制数目的请求会被阻塞
- 浏览器并发请求有个数限制,分域名可以同时并发请求大量图片
10.页面的加载顺序
- html顺序加载,其中js会阻塞后续dom和资源加载,css不会阻塞dom和资源的加载
- 浏览器会使用prefetch对引用的资源提前下载
- 没有defer或async,浏览器会立即加载并执行指定的脚本
- 有async,加载和渲染后续文档元素的过程将和script.js的加载与执行并行进行(下载一部,执行同步,加载完就执行)
- 有defer,加载后续文档元素的过程将和script.js的加载并行进行(异步),但是script.js的执行要在所有元素解析完成之后,DOMContentLoaded事件触发之前完成
11.计算机网络的分层概述
- tcp/ip模型:从下往上分别是链路层,网络层,传输层,应用层
- osi模型:从下往上分别是物理层,链路层,网络层,传输层,会话层,表示层,应用层
12.js/css缓存问题
- 浏览器缓存的意义在于提高了执行效率,但是也随之带来一些问题,导致修改了js、css,客户端不能更新
- 都加上了一个时间戳作为版本号
- <script type="text/javascript" src="{js文件路径}?version=XXXXXX"></script>
13.说说tcp传输的三次握手 四次握手策略
三次握手:
- 为了准确无误地吧数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,他一定会向对方确认是否送达,握手过程中使用TCP的标志:SYN和ACK
- 发送端首先发送一个带SYN的标志的数据包给对方,接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息
- 最后,发送端再回传一个带ACK的标志的数据包,代表“握手”结束
- 如在握手过程中某个阶段莫明中断,TCP协议会再次以相同的顺序发送相同的数据包
断开一个TCP连接需要“四次握手”
- 第一次挥手:主动关闭方发送一个FIN,用来关注主动方到被动关闭方的数据传送,也即是主动关闭方告诫被动关闭方:我已经不会再给你发数据了(在FIN包之前发送的数据,如果没有收到对应的ACK确认报文,主动关闭方依然会重发这些数据)。但是,此时主动关闭方还可以接受数据
- 第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号收到序号 +1(与SYN相同,一个 FIN占用一个序号)
- 第三次挥手:被动关闭方发送一个 FIN。用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会给你发送数据了
- 第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次握手
先放个连接:https://www.cnblogs.com/cooffeeli/p/TCP_Establish_Connection_Close_Connection.html
14.TCP和UDP的区别?
- TCP是基于连接的协议,也就是说,在正式收发数据前,必须和对方简历可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来
- UDP是与TCP相应的协议。他是面向非连接的协议,他不与对方建立连接,而是直接就把数据包发送过去了
- UDP适用于一次只传送少量数据,对可靠性要求不高的应用环境
15.HTTP和HTTPS
- HTTP协议通常承载与 TCP协议之上,在HTTP和TCP之间添加一个安全协议层(SSL或TSL),这个时候,就成了我们常说的HTTPS
- 默认HTTP的端口号为80,HTTPS的端口号为443
16.为什么HTTPS安全
因为网络请求需要中间有很多的服务器路由的转发,中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有,https之所有说比http安全,是因为他利用ssl/tls协议传输。包含证书,流量转发,负载均衡,页面适配,浏览器适配,refer传递等,保障了传输过程的安全性
17.关于http 2.0
- http/2 引入了“服务端推”的概念,它允许服务端在客户端需要数据之前就主动的将数据发送到客户端缓存中,从而提高性能
- http/2提供更多的加密支持
- http/2使用多路技术,允许多个消息在一个连接上同时交差
- 它增加了头压缩,因此即使非常小的请求,其请求和响应和header都只会占用小比例的带宽
18.defer 和 async
- defer并行加载js文件,会按照页面上script标签的顺序执行
- async并行加载js文件,下载完成立即执行,不会按照页面上script标签的顺序执行
19.Cookie的弊端
cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但是有很多局限性
第一:每个特定的域名下最多生成20个cookie
- IE6或更低的版本,最多20个cookie
- IE7和之后的版本最多50cookie
- chrom和safari没有做硬性限制
第二:IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie
- cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节
- IE提供了一种存储可以持久化用户数据,叫做userdata,从IE5.0就开始支持。每个数据最多128K,每个月名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,就一直会在
优点:极高的扩展性和可用性
- 通过良好的编程,控制保存在cookie中的session对象的大小
- 通过加密性和安全传输技术(SSL),减少cookie被破解的可能性
- 只在cookie中存放不敏感数据,即使被盗也不会有重大损失
- 控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie
缺点:
- cookie数量和长度的限制,每个domain最多只能有20调cookie,每个cookie的长度不超过4KB,否则会被截掉
- 安全性问题,如果cookie被人拦截了,那人就可以取得所有的session信息,即使加密也于事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就行
- 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器保存一个计数器,如果我们把这个计数器保存在客户端,那么他起不到任何作用
20.浏览器本地存储
- 较高版本的刘拉你中,js提供了sessionStorage和globalStorage。在HTML5提供了localStorage来取代globalStorage
- HTML5中的web storage包括了两种存储方式:sessionStorage和 localStorage
- sessionStorage用于本地存储一个会话中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据随之销毁,因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储
- 而localStorage用于持久化的本地存储,除非主要删除数据,否则数据是永远不会过期的
21.web storage 和 cookie的区别
- web storage的概念和cookie相似,区别是为更大容量存储设计的,cookie的大小是受限的,并且每次请求一个新的页面的时候cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用
- 除此之外,web storage拥有serItem,getItem,removeItem,clear等方法,cookie得自己封装setCookie,getCookie
- 但是cookie也是不可或缺的:cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在,而web stroage仅仅是为了在本地“存储”在存在
- 浏览器的支持除了IE7及以下不支持外,其他标准都会完全支持(ie及FF需要在web服务器里进行),值得一提的是IE总是办好事,例如IE7,IE6的userData其实就是js本地存储的解决方法,通过简单的代码封装就可以同意到所有的浏览器都支持web storage
- localStorage和sessionStorage都具有相同的操作方法,例如setItem,getItem,removeItem等
22.cookie 和 session的区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上
- cookie不是很安全,别人分析存放在本地的cookie进行cookie欺骗
- 考虑到安全应当使用session
- session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能
- 考虑到减轻服务器性能方面,应当使用cookie
- 单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie
所以个人建议:
- 将登陆信息等重要信息放在session
- 其他信息如果需要保留,可以放在cookie
23.常见兼容性问题?
- 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已经独立识别
.a{ background-color: #ccc; /*所有识别*/ .background-color: #ccc\9; /*IE6,7,8识别*/ +background-color: #ccc; /*IE6,7识别*/ _background-color: #ccc; /*IE6识别*/ }
- 怪异模式问题:漏写DOCTYPE声明。firefox仍然会按照标准模式来解析网页,但是IE中会触发怪异模式,为了避免不必要的麻烦,最好声明<doctype html> 良好习惯
IE6浏览器常见的BUG
1.IE6不支持min-height,解决办法使用css hack
.target{ min-height: 100px; height: auto !important; height: 100px; //IE6下内容高度超过会自动扩展高度 }
2.ol内的序号全为1,不递增。
为li设置样式display: list-item
3.未定位父元素overflow: auto;,包含position: relative;子元素,子元素高于父元素时会溢出
子元素去掉position: relative
不能为子元素取消定位时,父元素position:relative
4.IE6只支持a标签的:hover伪类
使用js为元素监听mouseenter,mouseleave事件,添加类实现效果
5.IE5-8不支持opacity,
.opacity{ opacity: 0.4; filter: alpha(opacity=60); /* for IE5-7 */ -ms-filter: "progid: DXImageTransform.Microsoft.Alpha(Opacity=60)"; /* for IE 8*/ }
6.IE6在设置height小于font-size时高度值为font-size
font-size:0;
7.IE6不支持PNG透明背景
IE6下使用gif图片
8.IE6-7不支持display: inline-block
设置inline并处罚hasLayout
display: inline-block; *display: inline; *zoom: 1;
9.IE6下浮动元素在浮动方向上与父元素便捷接触元素的外边距会加倍
使用padding控制边距
浮动元素display: inline;
10.通过块级元素设置宽度和左右margin为auto时,IE6不能实现水平居中
为父元素设置text-align: center