(该文章包含了html、css、js、浏览器等相关的基础题目,是基础前端每次面试前必须掌握的基础点。ps:所有答案均源于我的个人理解,如有不对欢迎指正与补充~)
一、HTML
1.XHTML和HTML有什么区别?
答:HTML是超文本标记语言,一种基于web网页设计的语言,而XHTML是基于XML的标记语言。而什么是XML呢?可以将XML理解为一个纯文本,你可以定义任意标签,主要用来记录某个信息,需要自己编写软件或程序才能传送读取这个文本。
2.简述一下你对HTML标签语义化的理解?
答:(1)为了让页面的内容结构化,在没有css的情况下也能显示出清晰的结构;
(2)有很好的可读性,便于团队开发与维护;
(3)利于SEO(搜索引擎优化),方便爬虫抓取有效信息(因为爬虫依赖标签来确定上下文和各个关键字的权重);
3.Doctype有什么作用?严格模式与混杂模式如何区分?
答:Doctype用来告知浏览器的解析器用什么文档标准来解析这个文档。如果Doctype存在,那么该文档便一严格模式呈现;如果Doctype不存在或格式不正确,则导致文档以混杂模式呈现。
4.列举几个行内元素与块级元素?它们的区别?(按自己的记忆列举几个即可)
答:行内元素:a, b, span, img, input,select等;
块级元素: p, div, ul, ol, li等。
区别:块级元素独占一行,行内元素可一行排列多个,同时都可以通过display属性来重新定义它们的类型。
5.页面导入样式时,link和@import有什么区别?
答:(1)作用不同:@import是css提供的,只能用于加载css,而link属于XHTML标签。
(2)加载顺序不同:页面在加载时,link引入的会被同时加载,而@import引入的则是在页面加载完成后才加载。
(3)兼容不同:@import只兼容IE5以上浏览器,而link不存在兼容问题。
6.简述一下src和href的区别。
答: href 是指向网络资源所在位置,src是指向外部资源的位置。
7.简述一下BFC。
答:块级格式化上下文,是页面盒模型布局中的一种 CSS渲染模式,相当于一个独立的容器,主要用于清除浮动、防止同一盒子里的相邻元素的外边距重叠的问题。创建BFC的方法有:(1)html根元素;(2)float浮动;(3)absolute绝对定位;(4)overflow不为visible;(5)display为表格布局或者弹性布局。
8.html5新增了哪些新特性?
答:语义标签,如:<hrader></header>、<footer></footer>、<nav></nav>;
增强了表单的type类型,如:color、date、search、range等;
新增音频(audio)和视频(video)标签;
新增canvas绘图;
(仅列举了几种)
二、CSS
1.css盒模型有哪些,它们有什么区别?
答:分w3c标准盒模型和IE标准的怪异盒模型。它们的区别是:标准盒子里的content不包括border及padding,而怪异盒模型里的content包含border及padding。
2.css3新增了哪些属性?
答:文字阴影(text-shadow)、边框的圆角(border-radius)、盒子模型(box-sizing)、一些动画属性、转换(translate);
3.列举你所知道的让一个元素隐藏的方法。
答:(1)display: none;
(2)visibility:hidden;
(3)opacity:0;
(4)position:absolute;left:-10000px;
4.如何让一个盒子垂直水平居中(至少列举三种)。
答: html:
<div class="parent">
<div class="child"></div>
</div>
css默认属性:
.parent: {
width:1000px;
height: 500px;
}
.child {
width: 100px;
height:100px;
background: gray;
}
(这里只列举了我比较熟悉的三种)
方法1:利用定位
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: 50px; /*child盒子高度的一半*/
margin-left:50px;/*child盒子宽度的一半*/
}
方法2:利用margin:auto;
.parent {
position: relative;
}
.child {
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left:0;
}
方法3:利用flex
.parent {
display: flex;
justify-content: center;
align-items: center;
}
5.列举几种清除浮动的方法。
答:css固定样式
.parent {
width: 300px;
border: 1px solid red;
}
.left {
float:left;
width: 100px;
height: 100px;
background: green;
}
.right {
float: left;
width: 100px;
height: 100px;
background: yellow;
}
方法1:clear:both;
<div class="parent">
<div class="left"></div>
<div class="right"></div>
<div style="clear:both"></div> <!--在父元素里新加一个元素并为其添加clear:both属性-->
</div>
方法2:为父组件添加:overflow:hidden;
.parent {
overflow:hidden;
}
方法3:给父组件一个固定高度
.parent {
height: 300px;
}
方法4:clearfix (推荐)
给父组件添加一个类名<div class="parent clear-fix"></div>
增加伪类元素:
.clear-fix::after {
content:"";
display: block;
clear:both;
}
6.px、em、rem是什么?有什么区别?
答:px是指屏幕上尺寸大小,是确定的单位;em是相对于父元素尺寸的单位,是相对单位;rem是在em基础上,css3新增的相对单位,不过是相对于根元素的尺寸。
三、浏览器与HTTP
1.浏览器的渲染过程是怎样的?
答:地址栏输入url请求资源 --> 浏览器根据返回的HTML文件,构造一棵dom树;同时css解析出css规则 --> 两者关联生成render树 --> 根据render树来计算各个dom在浏览器中的位置,输出layout树(layout布局) --> 渲染layout树
2.浏览器的存储方式有哪些?它们有什么区别?
答:常用的有cookie、localStorage和sessionStorage。cookie一般由服务器生成,可以设置过期时间,存储空间只有4k左右,一般用于与服务端通信,携带在请求头header上;localStorage会一直存储在浏览器上,除非被清理,存储空间能达到5M,并且自己携带getItem与setItem方法,不过它只能存字符串,一般要配合JSON.stringify()与JSON.parse()使用。sessionStorage则是页面关闭就被清理,存储空间有5M。
3.get和post有什么区别?
答:get的参数放在url上,直接暴露出去,不太安全,而post的参数是放在body里;get的参数是有长度限制的,而post没有;get在浏览器回退时不会产生什么影响,而post会再次发生请求;get会被浏览器自动cache,而post不会。(ps:我面试大概会说这几点,还不全面,其余的你们可以自己搜索补充)
4.浏览器输入url会发生什么?
答:DNS域名解析 --> 浏览器与目标服务器建立TCP连接 --> 浏览器向服务器发送一条HTTP请求 --> 服务器向浏览器返回一条HTTP报文 --> 浏览器渲染 --> 关闭TCP连接
-------------------
ps:偶尔会被问到建立TCP连接的过程(三次握手),这里建议大家参照这个回答关于TCP三次握手,这是我见过最好的解读了,通俗易懂
5.http与https有什么区别?
答:https协议需要申请到CA证书,一般免费的比较少;http传输的内容都是明文,https的则被加密过;https可以有效的防止被运营商劫持;http与https使用的连接方式不同,端口也不一样。
四、JavaScript
1.js的基本数据类型有哪些?(typeof可识别哪些类型?)
答:object、string、number、boolean、null、undefined六种。
------------
延伸:typeof识别的类型有:object、string、number、boolean、undefined、function(识别不了null,却能识别function)。typeof(null)返回的是object。typeof可以识别数组吗?不可以。typeof([0,1,2,3])返回"object",判断是否是数组可以使用Array.isArray([0,1,2,3]),返回true。
2.null与undefined的区别?
答:null是一个空指针,还未被声明,而undefined是声明了一个变量,但还没有被初始化。
3.常用的数组方法有哪些?
答:slice、splice、push、unshift、sort、map、filter等。(ps:直接让你列举的比较少,大部分都会在题目里考察)
4.如何对一个数组去重?
答:方法一(最最最基础的方法):for循环套for循环,使用indexOf判断。
function unique(arr){
var result = [];
for(var i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) == -1)
result.push(arr[i]);
}
return result;
}
方法二:ES6新增的Set结构去重。
function unique(arr) {
return Array.from(new Set(arr))
}
5.var、let、const之间的区别。
答:var可以声明多个变量,而let只能声明一个;const声明以后必须要赋值,否则会报错;var不受限于块级,可以在声明上面访问变量,而let和const都受限于块级,在变量上面访问不到。
6.作用域。
答:ES5分为全局作用域与函数作用域。全局作用域里的变量可供全局使用,函数作用域里的变量则不能被外部使用。ES6新增了块级作用域,使用 { } 来划分。if(){ }else{}里的{ }就算是块级作用域了。(作用域链的变量只能向上访问,一直到windows终止,无法向下访问)
7.谈谈你对闭包的理解。
答:闭包就是一个函数套函数的过程,使用闭包可以突破作用域链,内部函数可以访问到外部函数的变量与参数,不过会常驻内存,增加内存使用量,并且使用不当容易造成内存泄漏。
8.原型与原型链。
答:(ps:这个问题很基础,但是用文字来说很晦涩,所以这里贴个例题,利于理解原型与原型链。来源:js原型和原型链)
先大概解释一下原型的几个规则:a.所有的引用类型(array、object、function)(它本身)都具有对象属性,可自由扩展。b.所有引用类型(array、object、function)都有一个隐藏的原型(_proto_),_proto_是一个普通对象。c.所有的函数(function)都有一个显性原型(prototype),也是一个对象(函数的_proto_)。d.当你想得到一个对象的某个属性值,它将先在本身对象里查找,找到就停止,找不到就继续查找隐藏原型。
function A() {}
function B(a) {
this.a = a;
}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a);
console.log(new B().a);
console.log(new C(2).a);
答案:1,undefined,2
解析:A:函数A本身原型没有属性a,通过A.prototype.a = 1,给函数A添加了属性a(函数都有显性原型prototype,是一个对象)并赋值为1,所以输出1。
B:函数B构造时,通过this.a = a;已经给B本身增加了属性a,通过B.prototype.a = 1;给B的_proto_也增加了属性a并赋值为1,低于它本身属性一级。所以在new B().a时,先查找本身是否具有a,一查查到了,但是没有传参数,所以没有赋值,输出undefined,并没有查到_proto_的a时候就结束了。
C:函数C和函数B一样,但不同的是,它存在参数的时候才会在本身增加属性a。所以new C(2).a时传入参数2,参数2存在,构建输出,同样没有查到_proto_上的a: 1。
9.聊一聊this。
答:this就是函数执行的上下文,主要有以下几种情况:(1)如果函数中的this没有调用对象,那么this直接指向window(严格模式除外,严格模式this为undefined);(2)如果函数中的this被不包含子对象的对象调用,指向该对象;(3)如果函数中this被包含子对象的对象调用时,this指向上一级对象;(4)如果将调用的对象赋值给某个变量,在需要时才调用,则this指向window。(ps:建议多找几个题看看,关于this出题考察的很多,一不小心就绕翻车了)
10.apply、call、bind的使用与区别。
答:call方法,call(obj, 1,2,3) 第一个参数为绑定的this对象,为null或者undefined时,this指向window对象,后面跟随其余的参数。
apply方法,apply(obj, [1,2,3])与call相同,第一个参数为绑定的this对象,为null或者undefined时,this指向window对象,第二个参数接收一个数组。
bind方法:参数与call一样。但是bind返回的是一个函数,而不会直接被调用。
上代码:
//call
var obj = {
who:"我"
}
function print(num1,num2,num3) {
console.log(this.who +"数"+num1+num2+num3)
}
print(1,2,3) //undefined数123,this指向为window,window上找不到who这个属性
print.call(obj, 1,2,3) //我数123,将this指向改为obj
------------------------
//apply
var obj = {
who:"我"
}
function print(num1,num2,num3) {
console.log(this.who +"数"+num1+num2+num3)
}
print(1,2,3) //undefined数123。this指向为window,window上找不到who这个属性
print.apply(obj, [1,2,3]) //我数123。将this指向改为obj
------------------------
//bind
var obj = {
who:"我"
}
function print(num1,num2,num3) {
console.log(this.who +"数"+num1+num2+num3)
}
var a = print.bind(obj,1,2,3)
console.log(a);//function print(...) {...} 返回print这个函数,并没有被调用
a();//我数123。调用它,才会被执行
11.同步与异步?Js是同步还是异步?
答:简单来说,同步就是需要等一件事做完才能接着做另一件事,有一个等待过程,而异步是可以把一件事放到任务栈,不需要等到这件事做完就可以接着做下一件事。js是单线程的,执行异步任务。比如setTimeout、setInterval等方法就是异步。
反手看个题:
console.log(1)
setTimeout(function () {
console.log(2)
},0)
console.log(3)
setTimeout(function () {
console.log(4)
},1000)
console.log(5)
//结果为 1 3 5 2 4
(ps:曾经有个笑话说前端出现问题找不到原因就加一个setTimeout,如果不行就把时间改长一些,如果还解决不了,那就gg了,去从头理逻辑吧~~)
12.什么是跨域?如何解决?(同源策略)
答:跨域是指从一个域名的地址访问另一个域名的资源,严格来说,只要协议、域名、端口有任一不同,就当作跨域。(同源策略是浏览器的一种安全策略,同源指协议、域名、端口完全一致,也是因为有同源策略的存在,才造成了跨域。)解决跨域的方法有:(1)JSONP:主要利用了script标签不受同源策略限制的特性来发送请求,但它只能发送get请求。 (2)CORS:全称是跨域资源共享,一般由后端配置,配置好前端可以直接使用Ajax进行请求。 (3)nginx反向代理。(ps:不局限于这三种,还有其它方法,可自行了解)
13.Ajax的原理是什么?有什么优缺点?
答:ajax简单来说就是在用户和服务器中间加了一个中间层,通过XmlHttpRequest对象来对服务器发出异步请求,从而获得数据资源,使用户操作与服务器响应异步化。优点是无刷新更新页面,使用异步与服务端通信,不打断用户操作,同时分担一部分后端工作,减少后端与服务器的负担;缺点是不支持浏览器的back按钮,它暴露了与服务器的交互过程,存在有安全隐患。
如何手写一个ajax:
var xhr = null;
xhr = new XMLHttpRequest();//创建连接
xhr.open("get", url, true);//连接服务器
xhr.send(null);//发送请求
xhr.onreadystatechange = function() { //接收请求
if(xhr.readystate == 4) {
if (xhr.status == 200) {
success(xhr.responseText)
} else {
fail(xhr.responseText)
}
}
}
14.es6新增了哪些东西?
答:新增了let和const用来声明变量;新增了块级作用域;新增了字符串模版;新增了解构赋值;新增了Promise对象;新增了箭头函数。
15.箭头函数和普通函数有什么区别?
答:最大的区别是this的指向问题,箭头函数的this是声明时的对象,而箭头函数是使用时的对象,其次是不可当作构造函数,不能使用new。(ps:当然还有别的区别,不过于我目前使用下来看这两点比较重要,特别是this)
16.Promise。
答:Promise是异步编程的一种解决方案。手写一个promise函数:
var promise = new Promise((resolve, reject) => {
if (success) {
resolve(value)
}else {
reject(value)
}
})
promise.then(() => {
//操作
})
来一题,关于promise异步与定时器:
let promise = new Promise(function(resolve, reject){
console.log("1");
resolve();
});
setTimeout(()=>console.log("2"), 0);
promise.then(() => console.log("3"));
console.log("4");
//答案:1、4、3、2
解析:then方法指定的函数是在当前脚本语言执行完以后才执行,then属于js引擎里的任务,setTimeout是浏览器任务队列里的,由于js引擎内部的方法优先于浏览器任务队列里的方法执行,所以虽然then与定时器都属于异步操作,却先执行then才执行setTimeout的原因。
17.前端有什么优化的方法?
答:(1)减少HTTP请求次数,合理利用缓存;(2)css图片压缩,比如多张图片合并为一张(雪碧图、精灵图)。个人觉得使用iconfont字体包也是一种优化;(3)压缩js、css等文件;(4)减少dom的操作;(5)减少作用域链的查找;
(ps:还有很多,我这里只大概列了一下,详细的可以自己再查找补充)