第一问:说一说盒模型?
得分点:
标准盒模型、怪异盒模型
标准回答:
CSS盒模型定义了盒的每个部分包含 margin
, border
, padding
, content
。根据盒子大小的计算方式不同盒模型分成了两种,标准盒模型和怪异盒模型。
首先,标准盒模型:给盒设置 width 和 height,实际设置的是 content box。padding 和 border 再加上设置的宽高一起决定整个盒子的大小。
其次,怪异盒模型:给盒设置 width 和 height,包含了padding和border ,设置的 width 和 height就是盒子实际的大小
设置标准盒模型:box-sizing:content-box
。
设置怪异盒模型:box-sizing:border-box
第二问:说一说JS变量提升?
得分点:
Var声明的变量声明提升、函数声明提升、let和const变量不提升
标准回答:
变量提升是指JS的变量和函数声明会在代码编译期,提升到代码的最前面。
变量提升成立的前提是使用Var
关键字进行声明的变量,并且变量提升的时候只有声明被提升,赋值并不会被提升,同时函数的声明提升会比变量的提升优先。
变量提升的结果:可以在变量初始化之前访问该变量,返回的是undefined。在函数声明前可以调用该函数。
加分回答:
使用let
和const
声明的变量是创建提升,形成暂时性死区,在初始化之前访问let
和const
创建的变量会报错。
第三问:说一说map和forEach的区别?
得分点:
map创建新数组、map返回处理后的值、forEach()不修改原数组、forEach()方法返回undefined
标准回答:
map 和 forEach 的区别:
map有返回值,可以开辟新空间,return出来一个length和原数组一致的数组,即便数组元素是undefined或者是null。
forEach默认无返回值,返回结果为undefined,可以通过在函数体内部使用索引修改数组元素。
加分回答:
map的处理速度比forEach快,而且返回一个新的数组,方便链式调用其他数组新方法。
第四问:说一说call apply bind的作用和区别?
得分点:
bind改变this指向不直接调用、call和apply改变this指向直接调用、apply接收第二个参数为数组 、call用于对象的继承 、伪数组转换成真数组、apply用于找出数组中的最大值和最小值以及数组合并、bind用于vue或者react框架中改变函数的this指向
标准回答:
call、apply、bind的作用都是改变函数运行时的this指向。
bind和call、apply在使用上有所不同:bind在改变this指向的时候,返回一个改变执行上下文的函数,不会立即执行函数,而是需要调用该函数的时候再调用即可,但是call和apply在改变this指向的同时执行了该函数。 bind只接收一个参数,就是this指向的执行上文。 call、apply接收多个参数,第一个参数都是this指向的执行上文,后面的参数都是作为改变this指向的函数的参数。
但是call和apply参数的格式不同,call是一个参数对应一个原函数的参数,但是apply第二个参数是数组,数组中每个元素代表函数接收的参数,数组有几个元素函数就接收几个元素。
第五问:说一说null和undefined的区别,如何让一个属性变为null?
得分点:
操作的变量没有被赋值、全局对象的一个属性、函数没有return返回值、值null
特指对象的值未设置
标准回答:
undefind是全局对象的一个属性,当一个变量没有被赋值或者一个函数没有返回值或者某个对象不存在某个属性却去访问或者函数定义了形参但没有传递实参,这时候都是undefined。
undefined通过typeof
判断类型是undefined
。
null代表对象的值未设置,相当于一个对象没有设置指针地址就是null。
null通过typeof
判断类型是object
。
在实际使用过程中,不需要对一个变量显式的赋值undefined,当需要释放一个对象时,直接赋值为 null 即可。
加分回答:
null 其实属于自己的类型 Null
,而不属于Object
类型,typeof
之所以会判定为 Object
类型,是因为JavaScript 数据类型在底层都是以二进制的形式表示的,二进制的前三位为 0 会被 typeof 判断为对象类型,而 null 的二进制位恰好都是 0 ,因此,null 被误判断为 Object
类型。 对象被赋值了null 以后,对象对应的堆内存中的值就是游离状态了,GC会择机回收该值并释放内存。因此,需要释放某个对象,就将变量设置为 null,即表示该对象已经被清空,目前无效状态。
第六问:说一说cookie sessionStorage localStorage的区别?
得分点:
数据存储位置、生命周期、存储大小、写入方式、数据共享、发送请求时是否携带、应用场景
标准回答:
Cookie、SessionStorage、 LocalStorage都是浏览器的本地存储。
共同点:都是存储在浏览器本地的
不同点:cookie是由服务器端写入的,而SessionStorage、 LocalStorage都是由前端写入的,cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是页面关闭的时候就会自动清除。
存储:cookie的存储空间比较小大概4KB,SessionStorage、 LocalStorage存储空间比较大,大概5M。
Cookie、SessionStorage、 LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面。在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、 LocalStorage不会。
加分回答:
由于它们的以上区别,所以它们的应用场景也不同,Cookie一般用于存储登录验证信息SessionID或者token,LocalStorage常用于存储不易变动的数据,减轻服务器的压力,SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。
第七问:说一说样式优先级的规则是什么?
得分点:
important
、行内样式、嵌入样式、外链样式、id选择器、类选择器、标签选择器、复合选择器、通配符、继承样式
标准回答:
CSS样式的优先级应该分成四大类:
- 第一类
important
,无论引入方式是什么,选择器是什么,它的优先级都是最高的。
- 第二类引入方式,行内样式的优先级要高于嵌入和外链,嵌入和外链如果使用的选择器相同就看他们在页面中插入的顺序,在后面插入的会覆盖前面的。
- 第三类选择器,选择器优先级:id选择器>(类选择器 | 伪类选择器 | 属性选择器 )> (后代选择器 | 伪元素选择器 )> (子选择器 | 相邻选择器) > 通配符选择器 。
- 第四类继承样式,是所有样式中优先级比较低的。
- 浏览器默认样式优先级最低。
第八问:说一下浮动?
得分点:
脱离文档流、盒子塌陷、 影响其他元素排版、伪元素 、overflow:hidden
、标签插入法
标准回答:
浮动的作用:设置浮动的图片,可以实现文字环绕图片,设置了浮动的块级元素可以排列在同一行,设置了浮动的行内元素可以设置宽高,同时可以按照浮动设置的方向对齐排列盒子。
设置浮动元素的特点:
- 设置了浮动,该元素脱标。元素不占位置
- 浮动可以进行模式转换(行内块元素)
浮动造成的影响:使盒子脱离文档流,如果父级盒子没有设置高度,需要被子盒子撑开,那么这时候父级盒子的高度就塌陷了,同时也会造成父级盒子后面的兄弟盒子布局受到影响。如果浮动元素后面还有其他兄弟元素,其他兄弟元素的布局也会受到影响。
清除浮动的方法: -伪元素清除浮动:给浮动元素父级增加 .clearfix::after { content: ''; display: table; clear: both; }
给浮动元素父级增加overflow:hidden
属性
加分回答:
三种清除浮动的特点和影响
- 伪元素清除浮动:不会新增标签,不会有其他影响,是当下清除浮动最流行的方法
overflow:hidden
:不会新增标签,但是如果父级元素有定位元素超出父级,超出部分会隐藏,在不涉及父级元素有超出内容的情况,overflow:hidden
比较常用,毕竟写法方便简洁
- 标签插入法:清除浮动的语法加在新增标签上,由于新增标签会造成不必要的渲染,所以这种方法目前不建议使用
第九问:说一说你对闭包的理解?
得分点:
变量背包、作用域链、局部变量不销毁、函数体外访问函数的内部变量、内存泄漏、内存溢出、形成块级作用域、柯里化、构造函数中定义特权方法、Vue中数据响应式Observer
标准回答:
闭包:一个函数和词法环境的引用捆绑在一起,这样的组合就是闭包。
一般就是一个函数A,return其内部的函数B,被return出去的B函数能够在外部访问A函数内部的变量,这时候就形成了一个B函数的变量背包,A函数执行结束后这个变量背包也不会被销毁,并且这个变量背包在A函数外部只能通过B函数访问。
闭包形成的原理:作用域链,当前作用域可以访问上级作用域中的变量。
闭包解决的问题:能够让函数作用域中的变量在函数执行结束之后不被销毁,同时也能在函数外部可以访问函数内部的局部变量。
闭包带来的问题:由于垃圾回收器不会将闭包中变量销毁,于是就造成了内存泄露,内存泄露积累多了就容易导致内存溢出。
加分回答:
闭包的应用:能够模仿块级作用域,能够实现柯里化,在构造函数中定义特权方法、Vue中数据响应式Observer中使用闭包等。
第十问:说一下浏览器输入URL发生了什么?
得分点:
DNS解析、TCP握手、HTTP缓存、重定向、服务器状态码、渲染引擎和JS引擎互斥、渲染过程、浏览器进程、网络进程、渲染进程
标准回答:
输入地址,浏览器查找域名的 IP 地址。
浏览器向该IP地址的web服务器发送一个HTTP请求,在发送请求之前浏览器和服务器建立TCP的三次握手,判断是否是HTTP缓存,如果是强制缓存且在有效期内,不再向服务器发请求,如果是HTTP协商缓存向后端发送请求且和后端服务器对比,在有效期内,服务器返回304,直接从浏览器获取数据,如果不在有效期内服务器返回200,返回新数据。
请求发送出去服务器返回重定向,浏览器再按照重定向的地址重新发送请求。 如果请求的参数有问题,服务器端返回404,如果服务器端挂了返回500。
如果有数据一切正常,当浏览器拿到服务器的数据之后,开始渲染页面同时获取HTML页面中图片、音频、视频、CSS、JS,在这期间获取到JS文件之后,会直接执行JS代码,阻塞浏览器渲染,因为渲染引擎和JS引擎互斥,不能同时工作,所以通常把Script标签放在body标签的底部。
渲染过程就是先将HTML转换成dom树,再将CSS样式转换成stylesheet,根据dom树和stylesheet创建布局树,对布局树进行分层,为每个图层生成绘制列表,再将图层分成图块,紧接着光栅化将图块转换成位图,最后合成绘制生成页面。