前端面试基础篇 一(附答案)

1. 说一下http和https

答:

http: 超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP)。

https: 是HTTP下加入SSL层,HTTPS的安全基础是SSL。

区别:http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全,HTTP 的端口号是 80,HTTPS 是 443

 

2. tcp三次握手,一句话概括

答: 

S代表服务器, C代表客户端

第一次握手:S只可以确认 自己可以接受C发送的报文段   

第二次握手:C可以确认 S收到了自己发送的报文段,并且可以确认 自己可以接受S发送的报文段

第三次握手:S可以确认 C收到了自己发送的报文段

 

3.几个很实用的BOM属性对象方法?

答:

什么是Bom? Bom是浏览器对象

(1)location对象

location.href-- 返回或设置当前文档的URL
location.search -- 返回URL中的查询字符串部分。例如 http://www.dreamdu.com/dreamdu.php?id=5&name=dreamdu 返回包括(?)后面的内容?id=5&name=dreamdu
location.hash -- 返回URL#后面的内容,如果没有#,返回空
location.host -- 返回URL中的域名部分,例如www.dreamdu.com
location.hostname -- 返回URL中的主域名部分,例如dreamdu.com
location.pathname -- 返回URL的域名后的部分。例如 http://www.dreamdu.com/xhtml/ 返回/xhtml/
location.port -- 返回URL中的端口部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回8080
location.protocol -- 返回URL中的协议部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回(//)前面的内容http:
location.assign -- 设置当前文档的URL
location.replace() -- 设置当前文档的URL,并且在history对象的地址列表中移除这个URL location.replace(url);
location.reload() -- 重载当前页面

(2)history对象

history.go() -- 前进或后退指定的页面数 history.go(num);
history.back() -- 后退一页
history.forward() -- 前进一页

(3)Navigator对象

navigator.userAgent -- 返回用户代理头的字符串表示(就是包括浏览器版本信息等的字符串)   ua
navigator.cookieEnabled -- 返回浏览器是否支持(启用)cookie

 

4.介绍知道的http返回的状态码

答:

100    Continue    继续。客户端应继续其请求

101    Switching Protocols    切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议

200    OK    请求成功。一般用于GET与POST请求

201    Created    已创建。成功请求并创建了新的资源

202    Accepted    已接受。已经接受请求,但未处理完成

203    Non-Authoritative Information    非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本

204    No Content    无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档

205    Reset Content    重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域

206    Partial Content    部分内容。服务器成功处理了部分GET请求

300    Multiple Choices    多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择

301    Moved Permanently    永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

302    Found    临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

303    See Other    查看其它地址。与301类似。使用GET和POST请求查看

304    Not Modified    未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

305    Use Proxy    使用代理。所请求的资源必须通过代理访问

306    Unused    已经被废弃的HTTP状态码

307    Temporary Redirect    临时重定向。与302类似。使用GET请求重定向

400    Bad Request    客户端请求的语法错误,服务器无法理解

401    Unauthorized    请求要求用户的身份认证

402    Payment Required    保留,将来使用

403    Forbidden    服务器理解请求客户端的请求,但是拒绝执行此请求

404    Not Found    服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

405    Method Not Allowed    客户端请求中的方法被禁止

406    Not Acceptable    服务器无法根据客户端请求的内容特性完成请求

407    Proxy Authentication Required    请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权

408    Request Time-out    服务器等待客户端发送的请求时间过长,超时

409    Conflict    服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突

410    Gone    客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置

411    Length Required    服务器无法处理客户端发送的不带Content-Length的请求信息

412    Precondition Failed    客户端请求信息的先决条件错误

413    Request Entity Too Large    由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息

414    Request-URI Too Large    请求的URI过长(URI通常为网址),服务器无法处理

415    Unsupported Media Type    服务器无法处理请求附带的媒体格式

416    Requested range not satisfiable    客户端请求的范围无效

417    Expectation Failed    服务器无法满足Expect的请求头信息

500    Internal Server Error    服务器内部错误,无法完成请求

501    Not Implemented    服务器不支持请求的功能,无法完成请求

502    Bad Gateway    作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应

503    Service Unavailable    由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

504    Gateway Time-out    充当网关或代理的服务器,未及时从远端服务器获取请求

505    HTTP Version not supported    服务器不支持请求的HTTP协议的版本,无法完成处理

 

5.fetch发送2次请求的原因

答:

fetch发送post请求的时候,总是发送2次,第一次状态码是204,第二次才成功?

原因很简单,因为你用fetch的post请求的时候,导致fetch 第一次发送了一个Options请求,询问服务器是否支持修改的请求头,如果服务器支持,则在第二次中发送真正的请求。

 

6.click在ios上有300ms延迟,原因及如何解决

答:

<meta name="viewport" content="width=device-width, user-scalable=no">

 

7.说一下浏览器缓存

答:

缓存分为两种:强缓存和协商缓存,根据响应的header内容来决定。

强缓存相关字段有expires,cache-control。如果cache-control与expires同时存在的话,cache-control的优先级高于expires。

协商缓存相关字段有Last-Modified/If-Modified-Since,Etag/If-None-Match

 

8.在地址栏里输入一个URL,到这个页面呈现出来,中间会发生什么?

答:

输入url后,首先需要找到这个url域名的服务器ip,为了寻找这个ip,浏览器首先会寻找缓存,查看缓存中是否有记录,缓存的查找记录为:浏览器缓存-》系统缓存-》路由器缓存,缓存中没有则查找系统的hosts文件中是否有记录,如果没有则查询DNS服务器,得到服务器的ip地址后,浏览器根据这个ip以及相应的端口号,构造一个http请求,这个请求报文会包括这次请求的信息,主要是请求方法,请求说明和请求附带的数据,并将这个http请求封装在一个tcp包中,这个tcp包会依次经过传输层,网络层,数据链路层,物理层到达服务器,服务器解析这个请求来作出响应,返回相应的html给浏览器,因为html是一个树形结构,浏览器根据这个html来构建DOM树,在dom树的构建过程中如果遇到JS脚本和外部JS连接,则会停止构建DOM树来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐JS代码应该放在html代码的后面,之后根据外部央视,内部央视,内联样式构建一个CSS对象模型树CSSOM树,构建完成后和DOM树合并为渲染树,这里主要做的是排除非视觉节点,比如script,meta标签和排除display为none的节点,之后进行布局,布局主要是确定各个元素的位置和尺寸,之后是渲染页面,因为html文件中会含有图片,视频,音频等资源,在解析DOM的过程中,遇到这些都会进行并行下载,浏览器对每个域的并行下载数量有一定的限制,一般是4-6个,当然在这些所有的请求中我们还需要关注的就是缓存,缓存一般通过Cache-Control、Last-Modify、Expires等首部字段控制。 Cache-Control和Expires的区别在于Cache-Control使用相对时间,Expires使用的是基于服务器 端的绝对时间,因为存在时差问题,一般采用Cache-Control,在请求这些有设置了缓存的数据时,会先 查看是否过期,如果没有过期则直接使用本地缓存,过期则请求并在服务器校验文件是否修改,如果上一次 响应设置了ETag值会在这次请求的时候作为If-None-Match的值交给服务器校验,如果一致,继续校验 Last-Modified,没有设置ETag则直接验证Last-Modified,再决定是否返回304

 

9.画一条0.5px的线

答:

采用meta viewport的方式

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

采用border-image的方式

采用transform: scale()的方式

 

10.垂直居中的方法

答:

margin:auto法

margin负值法

利用flex

 

11.浮动清除

答:

方法一:使用带clear属性的空元素

在浮动元素后使用一个空元素如<div class="clear"></div>,并在CSS中赋予.clear{clear:both;}属性即可清理浮动。亦可使用<br class="clear" />或<hr class="clear" />来进行清理。

方法二:使用CSS的overflow属性

给浮动元素的容器添加overflow:hidden;或overflow:auto;可以清除浮动,另外在 IE6 中还需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1。

在添加overflow属性后,浮动元素又回到了容器层,把容器高度撑起,达到了清理浮动的效果。

方法三:给浮动的元素的容器添加浮动

给浮动元素的容器也添加上浮动属性即可清除内部浮动,但是这样会使其整体浮动,影响布局,不推荐使用。

方法四:使用邻接元素处理

什么都不做,给浮动元素后面的元素添加clear属性。

方法五:使用CSS的:after伪元素

结合:after 伪元素(注意这不是伪类,而是伪元素,代表一个元素之后最近的元素)和 IEhack ,可以完美兼容当前主流的各大浏览器,这里的 IEhack 指的是触发 hasLayout。

给浮动元素的容器添加一个clearfix的class,然后给这个class添加一个:after伪元素实现元素末尾添加一个看不见的块元素(Block element)清理浮动。

参考https://www.cnblogs.com/ForEvErNoME/p/3383539.html

 

12.calc属性

答:

Calc用户动态计算长度值,任何长度值都可以使用calc()函数计算,需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);

 

13.了解重绘和重排吗,知道怎么去减少重绘和重排吗,让文档脱离文档流有哪些方法

答:

DOM的变化影响到了预算内宿的几何属性比如宽高,浏览器重新计算元素的几何属性,其他元素的几何属性也会受到影响,浏览器需要重新构造渲染书,这个过程称之为重排,浏览器将受到影响的部分重新绘制在屏幕上 的过程称为重绘,引起重排重绘的原因有:

添加或者删除可见的DOM元素,

元素尺寸位置的改变

浏览器页面初始化,

浏览器窗口大小发生改变,重排一定导致重绘,重绘不一定导致重排,

减少重绘重排的方法有:

不在布局信息改变时做DOM查询,

使用csstext,className一次性改变属性

使用fragment

对于多次重排的元素,比如说动画。使用绝对定位脱离文档流,使其不影响其他元素

 

14.说一下闭包

答:

闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放。

 

15.说说前端中的事件流

答:

什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。

事件捕获阶段

处于目标阶段

事件冒泡阶段

addEventListener:addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

IE只支持事件冒泡

 

16.说一下事件委托

答:

简介:事件委托指的是,不在事件的发生地(直接dom)上设置监听函数,而是在其父元素上设置监听函数,通过事件冒泡,父元素可以监听到子元素上事件的触发,通过判断事件发生元素DOM的类型,来做出不同的响应。

举例:最经典的就是ul和li标签的事件监听,比如我们在添加事件时候,采用事件委托机制,不会在li标签上直接添加,而是在ul父元素上添加。

好处:比较合适动态元素的绑定,新添加的子元素也会有监听函数,也可以有事件触发机制。

 

17.懒加载怎么实现

答:

1)利用intersection observer   (注意:Intersection observer目前只能在Chrome63+和firefox58+使用)

开发者只需要注册一个observer去监控元素而不是写一大堆乱七八糟的视窗检测代码。注册observer之后我们只需要做的就是当元素可见时改变它的行为

2)利用事件

你可以使用scrollresizeorientationchange事件,再配合getBoundingClientRectAPI就可以实现懒加载了

3)CSS图像

思路是通过JavaScript检测到元素处于视窗中时,加一个class类名,这个class就引用了外部图片资源

参考https://www.jianshu.com/p/e86c61468285

 

18.改变函数内部this指针的指向函数(bind,apply,call的区别)

答:

call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以

通过apply和call改变函数的this指向,他们两个函数的第一个参数都是一样的表示要改变指向的那个对象,

第二个参数,apply是数组,而call则是arg1,arg2...这种形式。

xw.say.call(xh,"实验小学","六年级")

xw.say.apply(xh,["实验小学","六年级"])

参考https://www.cnblogs.com/cosiray/p/4512969.html

 

19. js的各种位置

答:

clientHeight:表示的是可视区域的高度,不包含border和滚动条

offsetHeight:表示可视区域的高度,包含了border和滚动条

scrollHeight:表示了所有区域的高度,包含了因为滚动被隐藏的部分。

clientTop:表示边框border的厚度,在未指定的情况下一般为0

scrollTop:滚动后被隐藏的高度,获取对象相对于由offsetParent属性指定的父座标(css定位的元素或body元素)距离顶端的高度。

 

20.JS中的垃圾回收机制

答:

由于字符串、对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。

垃圾回收的方法:标记清除、计数引用。

1)标记清除

这是最常见的垃圾回收方式,当变量进入环境时,就标记这个变量为”进入环境“,从逻辑上讲,永远不能释放进入环境的变量所占的内存,永远不能释放进入环境变量所占用的内存,只要执行流程进入相应的环境,就可能用到他们。当离开环境时,就标记为离开环境。

垃圾回收器在运行的时候会给存储在内存中的变量都加上标记(所有都加),然后去掉环境变量中的变量,以及被环境变量中的变量所引用的变量(条件性去除标记),删除所有被标记的变量,删除的变量无法在环境变量中被访问所以会被删除,最后垃圾回收器,完成了内存的清除工作,并回收他们所占用的内存。

2)引用计数法

另一种不太常见的方法就是引用计数法,引用计数法的意思就是每个值没引用的次数,当声明了一个变量,并用一个引用类型的值赋值给改变量,则这个值的引用次数为1,;相反的,如果包含了对这个值引用的变量又取得了另外一个值,则原先的引用值引用次数就减1,当这个值的引用次数为0的时候,说明没有办法再访问这个值了,因此就把所占的内存给回收进来,这样垃圾收集器再次运行的时候,就会释放引用次数为0的这些值。

 

21.如何理解前端模块化

答:

前端模块化就是复杂的文件编程一个一个独立的模块,比如js文件等等,分成独立的模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题,所以有了commonJS规范,AMD,CMD规范等等,以及用于js打包(编译等处理)的工具webpack

Commonjs:开始于服务器端的模块化,同步定义的模块化,每个模块都是一个单独的作用域,模块输出,modules.exports,模块加载require()引入模块。

AMD:中文名异步模块定义的意思。

requireJS实现了AMD规范,主要用于解决下述两个问题。

1.多个文件有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器

2.加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应的时间越长。

语法:requireJS定义了一个函数define,它是全局变量,用来定义模块。

 

22.对象深度克隆的简单实现

function deepClone(obj){
    var newObj= obj instanceof Array ? []:{};
    for(var item in obj){
        var temple= typeof obj[item] == 'object' ? deepClone(obj[item]):obj[item];
        newObj[item] = temple;
    }
    return newObj;
}

 

23.实现一个once函数,传入函数参数只执行一次

function ones(func){
    var tag=true;
    return function(){
        if(tag==true){
            func.apply(null,arguments);
            tag=false;
        }
        return undefined
    }
}

 

24.setTimeout、setInterval的区别

答:

setTimeout() 用于设定在指定的时间之后执行对应的函数或代码,   一次

setInterval() 用于设定每隔指定的时间就执行对象的函数。    多次

 

25.实现一个两列等高布局,讲讲思路

答:

为了实现两列等高,可以给每列加上 padding-bottom:9999px;

margin-bottom:-9999px;同时父元素设置overflow:hidden;

 

26.数组常用方法

答:

1)会改变原来的数组,不会创建新数组

shift()  :删除原数组第一项,并返回删除元素的值,如果数组为空则返回undefined。

unshift() :将参数添加到原数组开头,并返回数组的长度。

pop() :删除原数组最后一项,并返回删除元素的值,如果数组为空则返回undefined。

push() :将参数添加到原数组末尾,并返回数组的长度。

splice(index,howmany,item1,…..,itemX) :方法向/从数组中添加/删除项目,然后返回被删除的项目。index开始的下标,howmany删除多少个,item1…itemx为删除后插入的元素。

reverse() :用于颠倒数组中元素的顺序。

sort() :用于对数组的元素进行排序。参数可以为函数

 

2)原数组无变化,返回新数组

concat() :返回一个新数组,数组合并,参数可以是具体的值,也可以是数组对象。可以是任意多个。

slice(start,end)  :方法可从已有的数组中返回选定的元素。返回一个新的数组,包含从 start 到 end (不包括该元素)的中的元素。

join() :用于把数组中的所有元素放入一个字符串,元素是通过指定的分隔符进行分隔的。

 

3)ES5的

filter()过滤 :

array.filter(function(currentValue,index,arr), thisObject ) 
参数说明: 
function: 要对每个数组元素执行的回调函数。 
function(currentValue,index,arr) 
currentValue:必须。当前元素的值 
index:可选。当期元素的索引值 
arr:可选。当期元素属于的数组对象 
thisObject : 可选。在执行回调函数时定义的this对象。如果省略了 thisValue ,”this” 的值为 “undefined”

对数组中的每个元素都执行一次指定的函数(callback),并且创建一个新的数组,该数组元素是所有回调函数执行时返回值为 true 的原数组元素。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略,同时,新创建的数组也不会包含这些元素。

回调函数可以有三个参数:当前元素,当前元素的索引和当前的数组对象。

如参数 thisObject 被传递进来,它将被当做回调函数(callback)内部的 this 对象,如果没有传递或者为null,那么将会使用全局对象。

filter 不会改变原有数组,记住:只有在回调函数执行前传入的数组元素才有效,在回调函数开始执行后才添加的元素将被忽略,而在回调函数开始执行到最后一个元素这一期间,数组元素被删除或者被更改的,将以回调函数访问到该元素的时间为准,被删除的元素将被忽略。

function isBigEnough(element){//判断大于5的元素
    return (element>=5);
}
console.info(array);  //[1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 0, 33, 12]
console.info(array.filter(isBigEnough));//数组元素会依次传人 [5, 6, 6, 7, 8, 9, 33, 12]
console.info(array);  //[1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 0, 33, 12]

map()处理 :

array.map(function(currentValue,index,arr), thisValue); 
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。 
map() 方法按照原始数组元素顺序依次处理元素。 
注意: map() 不会对空数组进行检测。 
注意: map() 不会改变原始数组。

function sqrt(element){
    return element*element;
}
console.info(array);  //[1, 2, 3, 9, 0, 33, 12]
console.info(array.map(sqrt));  //[1, 4, 9, 81, 0, 1089, 144]
console.info(array);  //[1, 2, 3, 9, 0, 33, 12]

some()

方法用于检测数组中的元素是否满足指定条件(函数提供) 
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。 
如果没有满足条件的元素,则返回false。

function checknum(num) {
    return num >= 11;
}
console.info(array);  //[1, 2, 3, 9, 0]
console.info(array.some(checknum));  //false
array.push(11,12);
console.info(array);   //[1, 2, 3, 9, 0, 33, 12, 11, 12]
console.info(array.some(checknum));  //true

forEach()

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。 
注意: forEach() 对于空数组是不会执行回调函数的。

lastIndexOf() :  (indexOf() 同理)

array.lastIndexOf(item,start) 
lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。 
如果要检索的字符串值没有出现,则该方法返回 -1。 
该方法将从尾到头地检索字符串 stringObject,看它是否含有子串 searchvalue。开始检索的位置在字符串的 fromindex 处或字符串的结尾(没有指定 fromindex 时)。如果找到一个 searchvalue,则返回 searchvalue 的第一个字符在 stringObject 中的位置。stringObject 中的字符位置是从 0 开始的。

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var a = fruits.lastIndexOf("Apple");//return 2

reduce()

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。 
注意: reduce() 对于空数组是不会执行回调函数的。 
array.reduce(function(total, currentValue, currentIndex, arr), initialValue) 
total 必需。初始值, 或者计算结束后的返回值。 
currentValue 必需。当前元素 
currentIndex 可选。当前元素的索引 
arr 可选。当前元素所属的数组对象。

initialValue 可选。传递给函数的初始值

function getSum(total, num) {
    return total + num;
}
console.info(array);     //[1, 2, 3, 9, 0]
console.info(array.reduce(getSum));   //15
console.info(array);     //[1, 2, 3, 9, 0]

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章