前端面试知识总结(2019-5-24)
HTML
<!DOCTYPE html>- 定义:
DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档。<!DOCTYPE>声明必须是HTML文档的第一行,位于<html>标签之前 - 作用:避免浏览器的怪异模式,避免浏览器使用自己的怪异模式解析渲染页面,这样在所有的浏览器里显示的就都是一个样子了
- 定义:
HTML5为什么只需要写<!DOCTYPE HTML>HTML5不基于SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行)1
而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型1
标准模式与兼容模式各有什么区别?
- 标准模式的排版和
JS运作模式都是以该浏览器支持的最高标准运行。 - 在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作
- 标准模式的排版和
CSS
一、盒模型
- 本质就是一个盒子,它包括的内容从内到外依次是:实际内容,内边距,边框,外边距,在
chrome中展示如图所示:

- 当我们设置一个元素的宽高时候,其实设置的是它的实际内容大小,它实际占用的宽高还需要加上内边距,边框,和外边距,如上图所示中的实际宽度为
450px(300+50+50+50) 外边距合并(叠加):两个或多个块级盒子的垂直相邻边界会重合,它们的边界宽度是相邻边界宽度中的最大值,发生边距重叠的三种情况:父子元素边距重叠,兄弟元素边距重叠,空元素边距重叠,具体参见博客
边距重叠与BFC需要注意的是:只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并,另外水平边距是不会发生重叠的。
原因是如果块元素的 margin-top 与它的第一个子元素的margin-top 之间没有 border、padding、inline content、 clearance 来分隔,或者块元素的 margin-bottom 与它的最后一个子元素的margin-bottom 之间没有 border、padding、inline content、height、min-height、 max-height 分隔,那么外边距会塌陷。子元素多余的外边距会被父元素的外边距截断。
BFC:全称为
Block Formatting Context,即块级格式化上下文,用于解决边距重叠的问题。创建BFC的方法:浮动(float的值不为none);绝对定位元素(position的值为absolute或fixed);行内块(display为inline-block);表格单元(display为table、table-cell、table-caption等HTML表格相关属性);弹性盒(display为flex或inline-flex);overflow不为visible;css reset:用于改写HTML标签的默认样式。有些HTML标签在浏览器里有默认的样式,例如p标签有上下边距,li标签有列表标识符号等。这些默认样式在不同浏览器之间也会有差别。这必然会带来浏览器兼容问题。因此,可以使用CSS代码去掉这些默认样式,从而覆盖浏览器的CSS默认属性。box-sizing:它有如下几种属性content-box,默认值,可以使设置的宽度和高度值应用到元素的内容框。盒子的width只包含内容border-box, 设置的width值其实是除margin外的border+padding+element的总宽度inherit, 规定应从父元素继承box-sizing属性的值- 全局设置
border-box很好,首先它符合直觉,其次它可以省去一次又一次的加加减减,而且让有边框的盒子正常使用百分比宽度
另外补充用
div画三角形1
2
3
4
5
6
7
8<style>
.triangle {
width : 0;
height: 0;
border : 100px solid transparent;/*设置border为透明*/
border-top : 100px solid blue;
}
</style>
二、flex布局(弹性盒子布局)
- 布局的传统解决方案是:
display(设置行内\块级属性或flex布局),position(设置绝对定位,相对定位或默认定位)和float(浮动)属性 flex布局是什么:任何容器都可以指定为flex布局,行内元素也可以,但是设为flex布局之后,子元素的float,clear,vertical-align属性将失效- 基本概念:在
flex布局中,分为容器和容器中的项目,容器默认存在两根轴,水平的主轴main axis,和垂直的交叉轴cross axis。描述单个项目占据的大小的参数:main size和cross size 容器的属性:
flex-direction:描述项目子元素的垂直分布或水平分布
1
2
3
4
5<style>
.box {
flex-direction: row | row-reverse | column | column-reverse;/*水平|反向水平|垂直|反向垂直*/
}
</style>flex-wrap:描述子元素是否换行
1
2
3
4
5<style>
.box {
flex-wrap: nowrap | wrap | wrap-reverse;/*不换行|换行|反向换行*/
}
</style>注意:如果不换行,有可能造成子元素原有的宽度发生变化,在换行或反向换行时,子元素的宽度为设置的值
flex-flow:是
flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrapjustify-content: 描述子元素在水平方向的对齐方式
1
2
3
4
5<style>
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;/*左对齐|右对齐|居中|两端对齐项目等距|项目两侧间隔相等*/
}
</style>align-items:描述子元素在垂直方向的对齐方式
1
2
3
4
5<style>
.box {
align-items: flex-start | flex-end | center | baseline | stretch;/*上对齐|下对齐|居中|第一行文字对齐|未设置高度时充满容器*/
}
</style>align-content:描述多根水平轴线在交叉轴方向的对齐方式。只有一根轴线不起作用。
1
2
3
4
5<style>
.box {
align-content: flex-start | flex-end | center | space-between | space-around |stretch;/*同水平方式*/
}
</style>
项目的属性
order:描述项目的排列顺序,数值越小,越靠前,默认为
01
2
3
4
5<style>
.item {
order: <integer>;
}
</style>flex-grow:定义项目的放大比例,默认为
0(即使有剩余空间也不放大)1
2
3
4
5<style>
.item {
flex-grow: <number>;
}
</style>flex-shrink:定义项目的缩小比例,默认为
1(即使空间不足也不会缩小)1
2
3
4
5<style>
.item {
flex-shrink: <number>;
}
</style>flex-basis:定义在分配剩余空间之前,项目占据的主轴空间(
main size),默认值是项目本来的大小,它可以设为跟width或height属性一样的值1
2
3
4
5<style>
.item {
flex-basis: <length>;
}
</style>flex:是
flex-grow,flex-shrink,flex-basis的简写,默认值是0 1 autoalign-self:允许单个项目与其他项目不同的垂直方向的对齐方式,可以覆盖
align-items属性,默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch1
2
3
4
5<style>
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
</style>
flex布局实战:利用flex布局写的筛子
三、CSS居中
- 块级元素与行内元素:
h1,div,p,table,表单,列表,行内元素有a,img,input,lable,块级元素与行内元素转换用display属性,块级元素设为block,行内元素设为inline。由于行内元素无法设置宽高,因此,如果想要既是行内元素又能设置宽高可以将display值设为inline-block 块级元素水平居中:
设置外边距
1
2
3
4
5<style>
.box {
margin: 0 auto;
}
</style>绝对定位+负边距(父元素position非static)
1
2
3
4
5
6
7<style>
.box {
position: absolute;
left:50%;
margin-left: -50px; /*这里的值是这个元素的宽度的一半*/
}
</style>弹性盒子布局(具体参考第二部分)
块级元素垂直居中
绝对定位+负边距(父元素position非static)
1
2
3
4
5
6
7<style>
.box {
position: absolute;
top: 50%;
margin-top: -175px; /*这里的值是元素高度的一半*/
}
</style>绝对定位+父元素position非static+子元素transform
1
2
3
4
5
6
7
8
9
10<style>
.outside {
position: relative; /*父元素非static*/
}
.inner {
position: absolute;
top:50%;
transform: translateY(-50%); /*相对于自身高度,向上移动50%*/
}
</style>弹性盒子布局(具体见第二部分)
行内元素居中:
vertical-align:用于图片相对于文字的中心轴线居中text-align:仅用于文本的水平居中line-height: 可用于文本的垂直居中,这个属性描述的是行高,把一段文本的line-height设为父元素的高度就可以垂直居中- 图片在一个div中的居中可以用到绝对定位居中和弹性盒子居中,垂直水平都可以,用法同块级元素
关于
position
其中有几点需要注意:- 默认值是
static这个时候,如果其子元素想利用外边距取负值的方法居中的时候,就不会达到想要的效果,这个时候需要个想要居中的元素的父元素position赋值为非static即可 - 当一个元素有属性
z-index时候,另外需要给它的position赋值为absolute
- 默认值是
四、css其他几种布局方式
- 栅格布局(百分比)
- 格子布局(grid)见实战基本网格平均布局(适配手机)
- 圣杯布局
- 响应式布局:可以运用以上布局方式进行响应式布局
五、其他
- px,em,rem的区别?具体见菜鸟教程
JS
一、基础知识
- JS中的数据类型:js数据类型分为基本类型和引用类型,两者最主要的区别在于复制方面,前者是直接深复制,后者是类指针的引用类型,即浅复制。基本类型有
null,undefine,number,string,boolean,symbol,引用类型object,具体细分有Array,Date,RegExp,Function等等,比较特殊的一点就是还存在基本包装类型(因为他们还是遵循浅复制的原则),他们既是基本类型,但是又存在类似引用的方法。- null:表示一个空对象指针
- undefined: 未初始化的变量
- number:包括
NaN,需要掌握数值转换的几种方法:Number(),parseInt(),parseFloat() - string: 需要掌握转换字符串方法
toString() - boolean:只有两个字面值
true和false,其他所有类型的值都与这两个boolean等价,需要调用转型函数Bollean(),需要注意的是各种数据类型对应的转换规则 - symbol:直接使用
Symbol()创建新的symbol类型,并用一个可选的字符串作为其描述,注意字符串相同的两个变量不是全等的
类型判断的几种方法
typeof操作符
1
2
3
4var message = "some string";
console.log(typeof message);//"string"
console.log(typeof(message));//"string"
console.log(typeof 95);//"number"数据类型 | typeof返回值
—|—
字符串、””、’’ | string
对象、null、数组、正则表达式、日期 | object
函数 | function
布尔值 | boolean
数值 | number
未定义变量 | undefinedArray.isArray()
1
2if (Array.isArray(value)){ //对数组执行某些操作
}Object.prototype.toString.call(value):传入参数是需要检测的目标,返回值是
[object type],其中type取值可以是null、string、boolean、number、undefined、array、function、object、date、math1
2var message = "some string";
console.log(Object.prototype.toString.call(message));//[object String]
其他检测函数或操作符
- hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例 的原型中)是否存在,参数以字符串传入,返回布尔值
- isPrototypeOf(object):用于检查传入的对象的原型对象是否是调用该函数的对象,返回值为布尔值
instanceof 操作符:测试实例与原型链中出现过得构造函数,结果返回布尔值
1
2
3
4
5
6console.log(Object.prototype.isPrototypeOf(instance));//true
console.log(SuperType.prototype.isPrototypeOf(instance));//true
console.log(SubType.prototype.isPrototypeOf(instance));//true
console.log(instance instanceof Object);//true
console.log(instance instanceof SuperType);//true
console.log(instance instanceof SubType);//true
关于数组:
数组->字符串
1
2var colors = ["red", "blue", "green"];
console.log(colors.toString());//red,blue,green数组->特殊间隔的字符串
1
2
3var colors = ["red", "green", "blue"];
console.log(colors.join(",")); //red,green,blue
console.log(colors.join("||")); //red||green||blue字符串->数组
1
2
3
4var colorText = "red,blue,green,yellow";
var colors1 = colorText.split(",");//["red", "blue", "green", "yellow"]
var colors2 = colorText.split(",", 2);//["red", "blue"]
var colors3 = colorText.split(/[^\,]+/);//["", ",", ",", ",", ""]数组的栈方法(对数组的末位置操作)
1
2
3
4
5
6
7
8
9
10
11var colors = new Array();
var count = colors.push("red", "green");
console.log(count); //2
console.log(colors);//[ 'red', 'green' ]
count = colors.push("black");
console.log(count); //3
console.log(colors);//[ 'red', 'green', 'black' ]
var item = colors.pop();
console.log(item); //"black"
console.log(colors.length); //2
console.log(colors);//[ 'red', 'green' ]push向数组末尾增加值,返回值是修改后的数组的length,pop取出数组末尾的值,返回值是移除的项
数组的队列方法(对数组的首位置进行操作)
1
2
3
4
5var arr = [1, 2, 3, 4, 5]
console.log(arr.shift());//1
console.log(arr.length);//4
console.log(arr.unshift(6,7));//6
console.log(arr);//[ 6, 7, 2, 3, 4, 5 ]数组重排序
1
2
3
4
5
6
7
8
9
10
11
12//reverse
var values = [1, 2, 3, 4, 5];
values.reverse();
console.log(values);//5, 4, 3, 2, 1
//sort需要传入比较函数
var arr = [18, 12, 23, 4, 5, 26];
function compare (num1, num2) {
return num1 - num2;
}
arr.sort(compare);
console.log(arr); //[ 4, 5, 12, 18, 23, 26 ]连接数组
1
2
3
4var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
console.log(colors); //[ 'red', 'green', 'blue' ]
console.log(colors2); //[ 'red', 'green', 'blue', 'yellow', 'black', 'brown' ]删除数组中某些项(同字符串)
1
2
3
4
5var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1); //start
var colors3 = colors.slice(1,4); // start end
console.log(colors2); //[ 'green', 'blue', 'yellow', 'purple' ]
console.log(colors3); //[ 'green', 'blue', 'yellow' ]数组的删除插入和替换
1
2
3
4
5
6
7
8
9
10
11var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1);
console.log(colors);//[ 'green', 'blue' ]
console.log(removed); //[ 'red' ]
removed = colors.splice(1, 0, "yellow", "orange"); console.log(colors); //[ 'green', 'yellow', 'orange', 'blue' ]
console.log(removed); //[]
removed = colors.splice(1, 1, "red", "purple");
console.log(colors); //[ 'green', 'red', 'purple', 'orange', 'blue' ]
console.log(removed);//[ 'yellow' ]
原型链与继承
原型
原型就是包含特定类型的所有实例共享的方法和属性的对象。任何一个构造函数,不管是自定义的还是
js已有的,他们都带有一个名为prototype的属性,这个属性指向这种特定类型的原型对象,而这个原型对象又包含一个名为constructor的属性,这个属性指向这种类型的构造函数。构造函数的实例对象也有一个指针指向原型对象名为[[prototype]],可以用Object.getPrototypeOf(obj)获取原型链
即便自定义类型的构造函数有一个原型对象,但是终究还是指向
js本就有的类型,比如Object或Function。这就是因为原型链的存在,因为某个特定类型的原型对象其实是另一个类型的实例,如此层层递进,就构成了实例与原型的链条⛓继承
由于原型链的存在,实例对象,可以继承到原型链上所有的属性和方法,但是不能忘记,所有的引用类型都继承了
Object,而这个继承也是通过原型链实现的,所以默认的原型都会包含一个内部指针指向Object.prototype。还有一点需要注意除了Object.prototype和SuperType.prototype其他类型的原型都没有constructor属性

闭包
解释
闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式就是在一个函数内部创建另一个函数。内部函数可以在外部函数的参数部分,函数体部分以及返回值部分
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function createcompare (propertyName) {
return function (obj1, obj2) {
var value1 = obj1[propertyName];
var value2 = obj2[propertyName];
if (value1 < value2) {
return -1;
} else if (value1 > value2) {
return 1;
} else {
return 0;
}
}
}
var compare = createcompare("age");
console.log(compare({"age" : 2} , {"age" : 3}));实例:
见博客- 应用场景:迭代器,将变量存在内存中,与垃圾回收机制,内存销毁有关
call、apply与bind
- call与apply都是改变函数体内的
this指向,用于在特定作用域调用函数。两者最明显的区别就是对于call函数而言,第一个参数是this,其余参数都是直接传给函数,而apply第一个参数仍然是this,但是其余参数以数组形式或arguments传递。bind方法创建一个新的函数,在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
return sum.apply(this, arguments);
}
function callSum2(num1, num2){
return sum.apply(this, [num1, num2]);
}
function callSum3(num1, num2){
return sum.call(this, num1, num2);
}
console.log(callSum1(10,10)); //20
console.log(callSum2(10,10)); //20
console.log(callSum3(10,10)); //20
- call与apply都是改变函数体内的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var module = {
x: 42,
getX: function() {
return this.x;
}
}
var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined
var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
箭头函数
- 作用:更简短的函数,并且不用绑定
this 简短函数示例
1
2
3
4
5
6
7
8
9var arr = [1, 2, 3, 4];
var newarr = arr.map( function(element) {
return element += 1;
});
var newarr1 = arr.map((element) => { return element += 1})
var newarr2 = arr.map((element) => element += 1)
console.log(newarr);//[ 2, 3, 4, 5 ]
console.log(newarr1);//[ 2, 3, 4, 5 ]
console.log(newarr2);//[ 2, 3, 4, 5 ]
- 作用:更简短的函数,并且不用绑定
* 不绑定this示例
1
2
3
4
5
6
7
8
9
var arr = [1, 2, 3, 4];
var newarr = arr.map( function(element) {
return element += 1;
});
var newarr1 = arr.map((element) => { return element += 1})
var newarr2 = arr.map((element) => element += 1)
console.log(newarr);//[ 2, 3, 4, 5 ]
console.log(newarr1);//[ 2, 3, 4, 5 ]
console.log(newarr2);//[ 2, 3, 4, 5 ]
- 关于this
- 在严格模式下
this为undefined,在普通模式下this指向window - 对象方法调用用
this指向调用调用对象 call和apply可以显示绑定this指向- 在箭头函数中,
this指向外层作用域的this
- 在严格模式下
Vue
计网
一、DNS
- 概述
DNS是互联网的一项服务,它作为将域名和IP相互映射的一个分布式数据库,使用户更方便得访问互联网- 由解析器和域名器组成
DNS协议属于应用层协议,主要为其他应用协议服务,而不是直接面向用户。
- dns系统的层次结构:根域 > 顶级域(一级域)> 二级域等等如下图所示:

- 域名服务器:能提供域名解析的服务器,分为顶级域名服务器、权威域名服务器、本地域名服务器。域名服务器上记录的类型可以是
A,NS,MX,CNAME
需要注意的是,本地域名服务器不属于服务器的层次结构,每个ISP都有一个本地DNS服务器,当主机发出DNS请求时,该请求被发往本地DNS服务器。它起着代理的作用,转发请求到层次结构中。
* A:`address`,用户可以在这里设置子域名并指向自己目标主机上,从而通过域名找到服务器,还可以实现:泛域名解析(将该域名的子域名都指向同一个空间)、负载均衡(当相同子域名有多个目标地址时,表示轮询,可以达到负载均衡的目的,但需要虚拟主机服务商支持)
* CNAME:别名指向可以为一个主机设置别名。目标主机地址只能使用主机名,不能使用`IP`地址。`A`是优先于`CNAME`的
* MX:邮件交换记录,用于将以该域名为结尾的电子邮件指向对应的邮件服务器进行处理
* NS:记录从哪个`dns`服务器可以获得某个域的`dns`记录,即用于记录查询链
- dns提供的服务:映射域名与
IP地址,并提供别名;为邮件服务器提供别名;负载分配(一个域名多个IP的时候) - dns域名解析过程
- dns正向解析:分为递归查询(主机向本地服务器的查询,由请求的服务器直接返回权威答案)和迭代查询(由本地服务器逐步向各层服务器的查询过程)
- dns反向解析:在域名系统中,一个
IP地址可以对应多个域名,因此从IP出发去找域名,理论上应该遍历整个域名树,但是在Internet中不是这样实现的。为了完成逆向域名解析,系统提供一个特别域,该特别域成为逆向解析域in-addr.arpa。这样欲解析的IP地址就会被表达成一种像域名一样的可显示串形式,后缀以逆向解析域域名in-addr.arpa结尾 - dns缓存:先在本地缓存中查找若没有,查找
hosts文件,若还是没有,则像ns服务器发出请求,查询ns的缓存。缓存时间TTL是对象的服务器定义的
dns记录与报文:
- dns记录由四个部分组成:
type(标志这是一条什么记录),value(Name的对应值),Name(Value的对应值),TTL(本记录应该在缓存中呆多久) dns报文:如下图所示

- dns记录由四个部分组成:
- dns的安全性:dns大多数情况下是安全的
- 对于
DDos攻击,dns有包过滤系统和缓存服务,仅在DDos攻击指向顶级服务器的时候稍微有些困扰 - 可以被中间人攻击(伪造回答哄骗客户主机)和dns毒害攻击(伪造回答哄骗下一级dns服务器来缓存,从而欺骗客户主机)但是技术上很难实现
- dns服务器本身可被利用与攻击其他服务器,但是至今只是个例
- 对于
二、HTTP
- 一些web术语和基本概念、约定:web文档是由对象组成的,一个对象就是一个文件,对象一般由
url定位。url由两部分组成,一部分是主机名,另一部分是对象的路径名 - 概况:
http一般使用tcp作为传输层协议(但http协议中并没有规定必须使用它说)
三、TCP
四、cookie和session
五、缓存的实现方式
六、浏览器中输入一个url之后会发生什么事情
具体见博客SAP电话面试总结问题四
七、关于跨域
GIT
问题
- 闭包就是内部函数可以访问外部函数参数吗?那不一定非要放在返回值里面啊,放在函数体里面也可以啊,那放在参数里面可以吗