web前端面试会问:1、HTML和HTML5相关知识点,比如“什么是语义化”,“HTML5新特性有哪些”;2、CSS以及JS知识点,比如“如何实现垂直居中”,“js闭包是什么”等等问题。
web前端面试一般都会问:HTML和HTML5相关知识点,比如什么是语义化,HTML5新特性有哪些;CSS以及JS知识点,比如如何实现垂直居中,js闭包是什么等等问题
本篇文章收集了一些面试中经常会遇到的面试题,并给出了相应的答案,具有一定的参考作用,希望能帮到更多的前端面试者以及学习前端的人。
【推荐教程:JavaScript教程】
HTML/HTML5
1、知道语义化吗?说说你理解的语义化,如果是你,平时会怎么做来保证语义化?
像html5的新的标签header,footer,section等就是语义化
一方面,语义化就是让计算机能够快读的读懂内容,高效的处理信息,可以对搜索引擎更友好
另一方面,便于与他人的协作,他人通过读代码就可以理解你网页标签的意义
去掉或者丢失样式的时候能够让页面呈现出清晰的结构
有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重
方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义方式来渲染网页
便于团队开发和维护,语义化更具有可读性,是下一步把网页的重要动向,遵循W3C标准的团队都要遵循这个标准,减少差异化
2、介绍HTML5的新特性
新的DOCTYPE声明
完全支持css3
video和audio
本地存储
语义化表圈
canvas新事件如 ondrag onresize
3、如果解决ajax无法后退的问题
html5里引入了新的API,即:history.pushState,history.replaceState
可以通过pushState和replaceSate接口浏览器历史,并且改变当前页面的URL
onpopstate监听后退
4、websocket和ajax轮询
websocket是html5中提出的新的协议,可以实现客户端与服务器的通信,实现服务器的推送功能
优点是,只要简历一次连接,就可以连续不断的得到服务器推送消息,节省带宽和服务器端的压力。
ajax轮询模拟常连接就是每隔一段时间(0.5s)就向服务器发起ajax请求,查询服务器是否有数据更新
缺点就是,每次都要建立HTTP连接,即使需要传输的数据非常少,浪费带宽
5、web worker和websocket
worker主线程
通过worker = new worker(url)加载一个js文件来创建一个worker,同时返回一个worker实例
通过worker.postMessage(data)方法来向worker发送数据。
绑定worker.onmessage方法来接收worder发送过来的数据
可以使用worker.terminate()来终止一个worder的执行。
websocket
是web应用程序的传输协议,它提供了双向的,按序到达的数据流。他是一个HTML5协议,websocket链接是持久的,通过在客户端和服务器之间保持双向链接,服务器的更新可以被及时推送给客户端,而不需要客户端以一定的时间去轮询
6、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)
1.设置border-box width 33.33%
2.flexbox flex:1
3.实现两栏布局有哪些方法
方法一:
*{ margin: 0; padding:0; } html,body{ height: 100%; } #left{ width: 300%; height: 100%; float: left; } #right{ height: 100%; margin-left: 300px; background-color: #eee; }
方法二:
*{ margin: 0; padding: 0; } html,body{height: 100%;} #left{ width: 300px; height: 100%; float: left; } #right{ height: 100%; overflow: hidden; backrgound-color: #eee; }
以上第二种方法,利用创建一个新的BFC(块级格式化剩下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。
它可以通过下一任和一种方式来创建
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属性定义了项目的固定空间
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相对于根元素
8、清除浮动
利用clear属性进行清理
父容器结尾插入空标签
<div style="clear: both;"></div>
利用css伪元素:
.clearfix:after { content: "."; height: 0; visibility: hidden; display: block; clear: both; }
将父容器形成BFC
BFC能清理浮动主要运用的是它的布局规则:
内部的Box会在垂直方向,一个接一个的放置
box垂直方向的距离由margin决定。属于同一个BFC的两个相邻box的margin会发生重叠
每个元素margin box的左边,与包含快border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此
BFC的区域不会与float box重叠
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也是如此
计算BFC的高度时,浮动元素也参与计算
触发BFC有哪种方法?
根元素
float属性不为none
position为absolute或fixed
display为inline-block,table-cell,table-caption,flex,inline-flex
overflow不为visible
9、position的值, relative和absolute分别是相对于谁进行定位的?
relative:相对定位,相对于自己本身在正常文档流中的位置进行定位。
absolute:生成绝对定位,相对于最近一级定位不为static的父元素进行定位。
fixed: (老版本IE不支持)生成绝对定位,相对于浏览器窗口或者frame进行定位。
static:默认值,没有定位,元素出现在正常的文档流中。
sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。
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);
11、介绍sass
定义变量css嵌套,允许在代码中使用算式,支持if判断for循环
12、transition 和 margin的百分比根据什么计算?
transition是相对于自身;margin相对于参照物
13、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的权重.
JS
1、介绍一下闭包和闭包常用场景?
使用闭包主要为了设计私有的方法和变量,闭包的有点事可以避免变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念。
闭包有三个特性:
函数嵌套函数
函数内部可以引用外部的参数和变量
参数和变量不会被垃圾回收机制回收
闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包常见方式,就是在一个函数的内部创建另一个函数
应用场景,设置私有变量的方法
不适用场景:返回闭包的函数是个非常大的函数
闭包的缺点就是常驻内存,会增大内存使用量,使用不当会造成内存泄漏
2、为什么会出现闭包这种东西?解决了什么问题?
受javascript链式作用域链的影响,父级变量中无法访问到子级的变量值
3、介绍一下你所了解的作用域链,作用域链的尽头是什么?为什么?
每一个函数都有一个作用域,比如创建了一个函数,函数里面又包含了一个函数,那么现在又三个作用域,这样就形成了一个作用域链
作用域的特点就是,先在自己的变量范围中查找,如果找不到,就会沿着作用域链网上找
4、ajax创建的过程是怎样的,主要用到哪些状态码?
创建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、事件委托
利用冒泡原理,把时间加到父级上,触发执行效果
可以大量节省内存占用,减少事件注册
可以方便地动态添加和修改元素,不需要因为元素的改动而修改时间绑定
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); } } });
6、javascript的内存回收机制?
垃圾回收器会每隔一段时间找出那些不再使用的内存,然后为其释放内存
一般使用标记清除方法 当变量进入环境标记为进入环境,离开环境标记为离开环境
还有引用计数方法
stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放
基本数据类型存放在栈中
引用类型存放在堆内存中,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据
7、javascript中的this是什么,有什么用,指向上面?
全局代码中的this是指向全局对象
作为对象的方法调用时指向调用这个函数的对象
作为构造函数指向创建的对象
使用apply和call设置this
8、判断数组有哪些方法?
a instanceof Array
a.constructor == Array
Object.protype.toString.call(a) == [Object Array]
9、严格模式的特性?
对javascript的语法和行为,都做了一些改变
全局变量必须显式的声明
对象不能有重名的属性
函数必须声明在顶层
消除js语法的一些不合理,不严谨之处,减少一些怪异行为
消除代码运行的一些不安全之处,保证代码运行的安全
提高编译效率,增加运行速度
为未来新版本的js做好铺垫
10、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
11、图片懒加载
当页面滚动的时间被触发->执行加载图片操作->判断图片是否在可视区域内->在,则动态将data-src的值赋予该图片
12、webpack常用到哪些功能?
设置入口
设置输出目录
设置loader
extract-text-webpack-plugin将css从js代码中抽出并合并
处理图片文字等功能
解析jsx解析bable
13、函数组合继承
原型继承,构造函数继承,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()'
14、对作用域链的理解
作用域链的作用是保证执行环境里有权访问的变量和函数是有序耳朵,作用域链额变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的
15、js垃圾回收方法
标记清除(mark and sweep)
这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。
垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
引用计数(reference counting)
在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
在IE中虽然JavaScript对象通过标记清除的方式进行垃圾回收,但BOM与DOM对象却是通过引用计数回收垃圾的, 也就是说只要涉及BOM及DOM就会出现循环引用问题。
16、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中获取
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、跨域通信有哪些解决方案?
(1)JSONP
由于同源策略的限制,XMLHttpRequest只允许请求当前资源(域名、协议、端口)的资源,script标签没有同源限制,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。
通过动态