八股文

38 阅读13分钟

HTML篇

1、H5新增标签有哪些?

一、语义化标签

header、footer、nav、aside、section、article

语义化的意义?

1、更适合搜索引擎的爬虫爬取有效的信息,利于SEO。

2、对开发团队很友好,增加了标签的可读性,结构更加的清晰,便于团队的开发和维护。

二、多媒体标签

视频标签:video

属性:src、 Poster(加载等待画面的图片)、muted(静音)

音频标签: audio

属性:src、loop、controls(调出当前控件)

三、表单元素、控件

输入框input中新增 type,类型可为、email、url、data、number等

required、placeholder

2、src和href的区别

src和href都是对外部资源的引用,区别如下:

src: 表示对资源的引用,用在js脚本、img、frame等元素上,当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到该资源加载、编译、执行完成,所以js脚本会放在页面的底部,而不是头部。

href:表示超文本引用,指向一些网络资源,当浏览器识别它指向的文件时,就会并行下载资源,不会停止对当前文件的处理,用在a、link上

3、defer和async

参考博文:

blog.csdn.net/weixin_4256…

默认情况下,浏览器是同步加载js脚本的,即渲染引擎遇到 script标签就会停下来,等执行完脚本,再去继续向下渲染,如果是外部脚本,还必须加入脚本的下载时间。

加入脚本的很多而且体积很大的话,下载和 执行 就会占用很大的时间,照成浏览器堵塞,用户就会感觉卡死了,没有任何响应,体验极差,所以浏览器允许脚本的异步加载,方式如下:

关键字就是defer和async,脚本会异步加载。渲染引擎遇到这行命令就会开始下载外部的脚本,但是并不会等待其脚本下载完成和执行完成,而是直接执行后面的命令。

defer和async的区别:

defer:需要等待整个页面正常DOM渲染完成后,才会执行下载好的js脚本,并且是按下载完后的顺序执行。

async:当外部的js脚本下载完成后,渲染引擎会暂停DOM渲染,开始执行下载好的JS脚本的内容,在执行完成后,再去渲染。

简单的说:

defer是需要等DOM元素都渲染完成后,才去执行下载完成的js脚本

async是当js脚本下载完成后,开始执行的时候中断DOM渲染,执行js脚本的内容,执行完成再去渲染DOM元素

没有defer或async属性,浏览器会立即下载并执行相应的脚本,并且在下载和执行时页面的处理会停止。可能形成页面堵塞

不用异步加载的话可以把外部引入的脚本放在前即可

4、行内元素与块级元素

块级元素: 独占一行,可以设置宽高,设置margin和padding都有效,代表如下:

div、p、h1…h6、table、tr、ol、li、ul

行内元素元素: 可以排成一行,设置宽高无效,对margin设置左右方向有效,而上下无效,padding设置都无效,代表如下:

基本上都是文本标签

span、img、b、strong、font、br、a

5、title与h1、b与strong、i与em的区别

Strong表示的是重点内容,有语气加强的含义,,会重读,而展示强调的内容

b只是展示强调的内容

title属性没有明确意义只表示是个标题,H1则表示层次明确的标题,对页面信息的抓取也有很大的影响

i内容展示为斜体,em表示强调的文本

6、回流(重拍)与重绘

先了解下HTML文文件渲染的过程

image-20220106163008328

都发生在渲染DOM树(Render Tree)后的过程中,其中Layout是回流,Painting是重绘

回流:浏览器中进行布局的过程就是回流

重绘:浏览器进行 渲染就是重绘

触发回流的一些条件:

1、添加或者删除可见的DOM元素;

2、元素位置改变;

3、元素尺寸改变——边距、填充、边框、宽度和高度

4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;

5、页面渲染初始化;

6、浏览器窗口尺寸改变——resize事件发生时;

image-20220106163705728

触发重绘的一些条件:

1、改变背景色

2、改变透明度

简单的说,就是不影响布局的情况下,改变的就是重绘

image-20220106164151661

性能优化方法:

减少浏览器的回流行为达到性能优化。

1、用transform代替位移

2、用visibility:hidden透明度代替display:none

3、使用display:none技术,只引发两次回流和重绘;

4、使用cloneNode(true or false)和replaceChild技术,引发一次回流和重绘;

5、让元素脱离动画流,减少回流的Render tree的规模;

7、cookie、localStorage 和 sessionStorage的区别及应用实例

详解cookie

简单的理解是因为http协议的无状态性,所以需要cookie去把特别的信息保存下来,当然保存的是在浏览器中,下面简单的讲解下逻辑

1、浏览器向服务器发送请求,传输一些信息

2、服务器收到请求,在响应体中通过set-cookie返回字段,保存在浏览器中。

3、浏览器再次发送请求时会携带cookie,根据服务器中对比,做一个判断。

在前端的js代码中通过:

去设置cookie,其中cookie带有如下属性

max-age/expires:可设置cookie的有效时间,其中expires必须时GMT的时间格式,可用new Date().toGMTString()去对时间进行转换。在没有设置时间时,cookie会随着浏览器的关闭,而被删除

domain:可设置访问该cookie的域名

path:可设置访问此cookie的页面路径

Size:设置cookie的大小

http:cookie的httponly属性,如果为true。则只有在http请求头中会有此cookie的信息,而不能通过document.cookie来进行访问

删除cookie

只需要把cookie的有效时间设置为当前日期的前任何时间即可

下面是列子:

localStorage 和sessionStorage

前面得cookie作为一个存储手段进行举例,但是在H5中新增了两种存储方式,其中使用方法如下:

localStorage.key() :拿到指定key得值

localStorage.setItem('名','值'):设置相关的储存值

localStorage.getItem('名'):取出对应名的值

localStorage.removeItem('名'):移除掉相关的值

sessionStorage使用的方法和localStorage一致。

三者的区别

cookie具有时效性,可以手动的去设置需要保存的时间,内存大小大概为4KB,内容保存在客户端上,删除的话把过期时间设置为前一天即可。

localStorage,除非手动去删除,不然一直会保存,内存大小为5MB

sessionStorage,临时会话保存,相关页面关闭掉就自动删除,内容大小为5MB

建议理解三者的基本使用再去理解这面试题,因为工作中也能用到

8、同源策略与跨域问题

什么是同源策略?

借用阮一峰老师的描述:

image-20220205201415594

简单地说就是为了网页之间的安全性,但是在平常的工作中,我们会遇到别的资源请求问题,也就是跨域问,下面给出几种常见的跨域解决问题的方案

跨域解决方案

参考B站技术蛋老师的讲解

1、JSONP

json with padding,也就是JSON的填充方法。在服务器与客户端之间的格式我们常用的是JSON格式。

我们用script标签获取数据,其中的数据会被执行,所以我们一般会给数据外包一个js函数,然后再外包一层作为传输用的json格式。

我们知道通过script标签请求的资源中,并不会受到同源策略的限制,而jsonp方法就是通过这个方式去实现别的资源共享,简单原理如下:

原理可分为 客户端与服务器

客户端:客户端上去写一个函数,专门用来处理跨域获取服务器JSON数据的方法,在传入的url上写额外的参数,传到服务器,同时客户端收到服务器传过来的数据后,调用提前设定好的函数,执行服务器传过来的数据。

服务器:数据源是在服务器上存在的,而我们需要再然后服务器对额外的参数进行判断,把数据外包一个js函数,通过JSON的方式传给客户端。

image-20220205203014701

image-20220205203255464

2、CORS

当浏览器向服务器发起请求的时候,会在请求头中添加origin(协议+主机+端口),也就是表明自己的协议+主机+端口,当服务器接收到这个origin的时候,就得添加头部Access-Control-Allow-Origin到响应里面,浏览器看到服务器传回来的Access-Control-Allow-Origin,就可以进行判断是否进行跨域请求

image-20220205205058169

image-20220205205425242

核心其实就是设置Access-Control-Allow-Origin

9、检测数据类型的方法

1、typeof

typeof在检测null、object、array、data的结果中都是object,所以无法用来区分这几个类型的区别

image-20220223220519006

2、instanceof

缺点是只能检测该对象是否存在目标对象的原型上

[对象] instanceof [构造函数]

instanceof 用于判断对象类型,但以上情况的结果都为false,请注意。

instanceof 的原理

因为会一直往原型链上查找

L代表instanceof左边,R代表右边

3、constructor

constructor 不能判断null、undefind,因为他们不是构造对象

image-20220223221351705

4、Object.prototype.toString.call

可以检测出所有的数据类型

image-20220223222504029

在使用Array.prototype.toString.call的时候,遇到null、undefined会出现报错

10、阻止默认事件

在面试中我们会被问到事件冒泡、默认事件等概念,下面做一些简单的了解:

事件冒泡:

1.原理:元素自身的事件被触发后,如果父元素有相同的事件,如click事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一级根据嵌套关系向外触发,直到document/window,冒泡过程结束。

2.使用范围:冒泡事件只是针对于click相关的事件,还有click的分支事件:mouseup、mousedown

默认事件:

比如点击a标签会默认打开、input提交表单按钮,都是默认事件

阻止默认事件但是不阻止事件冒泡

event.preventDefault()

阻止事件冒泡阻止默认事件

event.stopPropagation();

在jquery中阻止事件冒泡和默认行为,在原生js中只阻止事件冒泡

return false

11、文档流,文本流清除浮动

文档流:

我理解的是页面中的块级元素等DOM元素按照默认的方式去进行排列

文本流:

网页页面上的一些文字的排列

清除浮动的方法及原理:

原理:其实就是让目标元素脱离文档流即可,手段有float:left、position中的绝对定位和固定定位等

方法:

1、用伪类去清除浮动

2、在浮动元素上添加一个空盒子,写上clear:both的样式

3、双伪类清除浮动

12、手写call、apply、bind

1、call

想要手写出就得知道它是怎么使用的,函数.call(绑定this指向,参数一,参数二,…)

image-20220225111457351

2、apply

apply和call的写法基本一至,就是二者接受的参数不同,面试apply的写法

函数.apply(this指向对象,[参数1,参数2,参数3…])

image-20220227125422710

3、bind

bind与前两个的区别如下

1、bind返回的是一个函数

2、如果是new出来的 ,返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype,且完成函数柯里化

image-20220227151331533

13、new的过程中发生了什么

其实new的过程中就是this指向改变、新创建一个实列的过程,如下

14、js的继承方式

1、原型链继承

关键点就是: 继承函数.prototype =new 被继承函数

缺点:

1、继承单一

2、子类无法向父类的构造函数传参

3、所有新实列都会共享父类实列的属性(原型上的属性也是共享的,一个实列修改了原型属性,另一个也会被修改)

2、原型继承

image-20220228112350530

缺点:子类实列共享了父类构造函数的引用属性,不能传参

3、构造函数继承

重点:借用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行)

优点:1、可以继承多个构造函数属性

​ 2、在子实列中可以向父实列传参

缺点:1、只能继承父实列的构造函数属性

​ 2、每新实列都会有父类构造函数的副本,臃肿

4、组合继承

重点:结合了两种模式的优点,传参和复用 特点:1、可以继承父类原型上的属性,可以传参,可复用。    2、每个新实例引入的构造函数属性是私有的。 缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。

5、寄生组合继承

优点

只调用了一次父类构造函数,只创建了一份父类属性 子类可以用到父类原型链上的属性和方法 6、extends继承

ES6出来的

​ 子类只要继承父类,可以不写 constructor ,一旦写了,则在 constructor 中的第一句话必须是 super 。