前端面试题

文章目录

后台管理权限怎么弄?

​ 首先后台管理系统的菜单的做成“活的”,即,菜单不能是纯粹的静态的,而应该是根据后端返回来的数据,来显示菜单的。
​ 前端登录(给后端发送用户名和密码),后端验证成功后,会根据登录的用户,给前端返回来菜单数据

登录注册界面

注册==:通过Ajax传到后台

$.ajax({
	type:"post",   url:"----.php",   data:{username:$().eq(0).val(), password: },
	success:
	error:
})
(2)用户密码加密MD5(不可逆)str = md5(md5($password),"beijing")

商城项目

(1)首页导航:数据下载

  $.ajax({url:(json数据)})     

(2)购物车:移入移出操作(加入购物车效果):事件委托(mouseenter , mouseleave)
(3)加入购物车操作: $.cookie()==null 先判读是否是第一次添加(是则简历cookie存储数据)(不是就判断之前是否添加过,是的话数量+1,不是的话新增商品数据)

JSON.parse(----)转数组     $.cookie("goods",JSON.stringify(-----),{   expires:7})

(4)购物车结算页(列表)
AJAX异步加载,要想异步串行,使用promise处理两次按顺序加载数据

使用swiper插件实现首页轮播图

<script src="js/zepto.js"></script>
<script src="js/swiper-3.4.2.jquery.min.js"></script>
<script>
//轮播图
$(document).ready(function () {
    var mySwiper = new Swiper ('.swiper-container', {
        direction: 'horizontal',  //轮播方向
        autoplay:2000,  //自动轮播
        loop: true,   //循环
        autoplayDisableOnInteraction : false  //用户操作后不停止
    });
});
</script>

队列和栈的区别

  • 队列先进先出,栈先进后出。
  • 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
  • 队列基于地址指针进行遍历,可以从头或尾部开始遍历,速度快
  • 栈是只能从头部开始取数据

HTTP和HTTPS

1.HTTP(超文本传输协议)的url以http://开头,而https以https://开头

(HTTP属于应用层)

2.http不安全(传输的数据未加密,明文),https相对安全(加入了SSL层)

3.http标准端口为80,https标准端口为443

4.在OSI网络模型中,https加密是在传输层完成的(SSL位于传输层)( 自上而下分别是应用层、表示层、会话层、传输层、网络层、数据链路层、物理层 )

5.HTTPS 内容经过对称加密,每个连接生成一个唯一的加密密钥( 服务器把公钥发送给客户端,并且服务器端保存着唯一的私钥 )

HTTP 2.0

1.允许多路复用(通过单一链接发送多重请求-响应信息,连接共享)

2.二进制分帧(分为更小的帧,并进行二进制编码)

3.首部压缩( 用 HPACK 算法,使用encoder来减少需要传输的header大小 )

4.服务器端推送( 能把客户端所需资源随着index.html一起发送到客户端,省去了客户端重复请求的步骤 )

HTTP状态码

200 服务器成功处理了请求

301 请求的页面已永久跳转到新的url

304 GET请求已被允许,而文档内容没改变

400:请求无效 401:当前请求需要用户验证

403:服务器已经得到请求,但拒绝执行

500:服务器内部错误

HTTP常用请求方式

  • GET 从指定资源中请求数据
  • POST 用于将数据发送到服务器以创建或更新资源
  • HEAD 与GET方法相同,但没有响应体,仅传输状态行和标题部分
  • PUT方法用于将数据发送到服务器以创建或更新资源
  • DELETE方法用来删除指定的资源
  • CONNECT方法用来建立到给定URI标识的服务器的隧道
  • OPTIONS方法用来描述了目标资源的通信选项
  • TRACE方法用于沿着目标资源的路径执行消息环回测试

HTTP常用请求头

cookie 、 Cache-Control(是否使用缓存) 、Referer(服务器访问的前一个页面)

connection(链接类型) 、 Expires(过期时间)

TCP和UDP的区别

1.TCP是面向连接的,可靠性高;UDP是无连接的,可靠性低(即发送数据前不需要先建立链接)。

2.TCP只能1对1;UDP支持1对1,1对多,多对一,多对多

3.TCP有三次握手、四次挥手等连接过程,会有延时,实时性差,过程复杂,易于攻击

UDP没有建立连接过程,实时性强,较安全

4.TCP传送的数据无差错、不丢失、不重复、按序到达(适合大数据量的交换)

​ TCP在IP协议上添加了序号机制、确认机制、超时重传机制等保证了传输的可靠性,不会出现丢包和乱序

TCP三次握手与四次挥手

TCP三次握手

(1)客户端发送带SYN标志的数据包,等待服务端确认

(2)服务器收到后,发送一个SYN标志和ACK确认标志

(3)客户端收到后,会向服务器发送ACK包确认

TCP四次挥手

(1)客户端向服务器发送带FIN标志的数据包

(2)服务器发送一个带ACK标志的信息告知客户端还有数据要发送

(3)服务器发送带FIN的数据包,通知可以断开

(4)客户端发送ACK确认标志

OSI七层模型

应用层、表示层、会话层、传输层、网络层、数据链路层、物理层 (物链网传会表应)

TCP/IP层次模型(分为 4 层)

TCP传输层 IP网络层
应用层、传输层、网络层、数据链路层

GET和 POST 的区别

判断:传回的报文有固定格式的 method 参数里面 看是get 还是 post, 浏览器会解析这个报文

  • GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符

    POST:一般用于修改服务器上的资源,对所发送的信息数量没有限制

  • GET方式需要使用Request.QueryString来取得变量的值 通过地址栏来传值

    POST方式通过Request.Form来获取变量的值,Post是通过提交表单来传值

  • get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存

    post不同,post做的一般是修改和删除数据的工作,所以必须与数据库交互,所以不能使用缓存

  • 小结:对于信息的获取一般使用get,在以下情况下最好使用post请求:

    ​ 向服务器发送大量数据(因为post没有发送数据的数量限制)

    ​ 无法使用缓存文件(会更新服务器上的文件)

    ​ 发送包含未知字符的用户输入时(亲身经历过GET的坑,泪目)

线程和进程的区别

  • 进程是资源分配最小单位,线程是程序执行的最小单位
  • 进程有自己独立的地址空间,每启动一个进程,系统都会为其分配地址空间,建立数据表来维护代码段、堆栈段和数据段,线程没有独立的地址空间,它使用相同的地址空间共享数据;
  • 进程对资源保护要求高,开销大,效率相对较低,线程资源保护要求不高,但开销小,效率高,可频繁切换;

进程间通信

  • 管道
  • 命名管道
  • 消息队列
  • 信号量
  • 共享内存

WebSocket的实现

1.websocket 是HTML5的协议,支持持久连续 (http不支持持久性链接);

2.websocket 基于http协议,2个属性upgrade设置为websocket ,connection设置为Upgrade

输入URL到页面加载完成发生了什么?

  • 浏览器的地址栏输入URL并按下回车。
  • 浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
  • DNS解析URL对应的IP。
  • 根据IP建立TCP连接(三次握手)。
  • HTTP发起请求。
  • 服务器处理请求,浏览器接收HTTP响应。
  • 渲染页面,构建DOM树。
  • 关闭TCP连接(四次挥手)。

浏览器渲染机制(重绘和重排)

  • 解析HTML,生成DOM树,解析css,生成CSSOM树
  • 将DOM树与CSSOM树结合,生成渲染树
  • 回流:根据渲染树,进行回流,得到节点信息(位置、大小)
  • 重绘:根据渲染树和回流得到的信息,得到节点绝对像素
  • 展示在页面上

重绘和重排

重排必定会导致重绘,但重绘不一定会重排

重排:当渲染树的一部分更新且节点尺寸发生了变化,浏览器会使渲染树部分失效,并重新构造渲染树。

  • 添加或删除可见的DOM元素
  • 元素位置改变
  • 元素本身的尺寸发生改变
  • 内容改变
  • 页面渲染器初始化
  • 浏览器窗口大小发生改变

重绘:元素外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观

  • 改变某个元素的背景色、文字颜色、边框颜色等等

防抖和节流

目的:都是为了防止频繁触发,消耗过多资源,甚至导致服务器崩溃

  • 防抖:防止抖动,因为抖动容易高频触发;防抖的核心就是延迟执行,当间隔大于规定时间,才会触发执行(实时搜索,拖拽)
  • 节流:节省流量,若在规定时间内仍频繁操作,请求不会直接发送,直到时间大于时间间隔,才会重新出发请求(抢购点击)

​ 防抖是延迟执行,等待时间超过规定时间才会执行;节流是立即执行,中间等待时间超过规定时间才会再次执行

强缓存和协商缓存

分为强缓存和协商缓存,根据header内容决定

  • 强缓存:(强制缓存) 当浏览器去请求某个文件的时候,服务端就在response header里面对该文件做了缓存配置

    response header 的cache-control,常见的设置是

    max-age : public客户端和代理服务器都可以缓存该资源 ,用户一旦刷新,则发起http请求

    no-cache: 跳过设置强缓存,但是不妨碍设置协商缓存

    no-store: 不缓存,这个会让客户端、服务器都不缓存

  • 协商缓存:与服务器协商(response header里面的设置)

    etag: '5c20abbd-e2e8'
    last-modified: Mon, 24 Dec 2018 09:49:49 GMT
    

    etag:每个文件有一个,改动文件了就变了

    last-modified:文件的修改时间,精确到秒

    请求资源时,把用户本地该资源的 etag 同时带到服务端,服务端和最新资源做对比。
    如果资源没更改,返回304,浏览器读取本地缓存。
    如果资源有更改,返回200,返回最新的资源。

    ETag 可以弥补 Last-Modified 判断的缺陷, 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改

web性能优化

  • 减少http请求(每个http都需要启动独立的线程去处理)
  • 合并CSS、合并javascript、合并图片:将浏览器一次访问需要的javascript和CSS合并成一个文件,这样浏览器就只需要一次请求。
  • 使用浏览器缓存(当静态资源文件发生变化时,通过****生成一个新的JS文件并更新HTML文件中的引用来更新js文件****,避免直接更新js文件中的内容。)
  • 懒加载,剩余的图片请求就都节省了。
  • 减少cookie传输,对于某些静态资源的访问,如CSS、script等,发送cookie没有意义,可以考虑****静态资源使用独立域名访问****
  • 避免Reflow & Repaint
  • 减少闭包的使用
  • css放在头部,将js文件放在尾部( js有可能影响dom的解析,比如在js里面新增dom等这些操作;css不能影响dom的解析 而 dom的渲染 是需要等js,css都解析完成后才进行的(浏览器就是这么机智),所以css js都阻止dom的渲染)

Cookie、SessionStorage、LocalStorage的区别

相同:都保存在浏览器端,且为同源,存储数据类型为字符串

  1. cookie在浏览器和服务器间来回传递,而sessionStorage、localStorage数据只在本地保存,不发送给服务器

  2. cookie在设置的cookie过期时间之前有效;

    ==sessionStorage:==仅在当前浏览器窗口关闭前有效,不持久;

    ==localStorage:==始终有效,持久

  3. cookie最大的作用就是存储sesssionId用来唯一标识用户

Cookie 和 Session的区别

  • cookie数据存在浏览器上,session存在服务器上
  • cookie不安全,别人可以分析本地cookie,单个cookie保存数据不超过4k
  • session会在一定时间内保存在服务器上,当访问过多,会比较占用服务器性能
  • 登录等重要信息放在session

Cookie 如何防范XSS攻击

xss(跨站脚本攻击)指攻击者在返回的HTML中嵌入JS脚本,为减轻攻击,需要在HTTP头部配上set-cookie:

httponly这个属性可以防范xss,禁止js脚本访问cookie

secure这个属性告诉浏览器仅在请求为https时发送cookie

Fetch发送2次请求的原因

fetch发送post请求时,第一次发送了一个Options请求(返回204:服务器成功处理了请求,但不需要返回任何内容 ),询问服务器是否支持修改请求头,如果支持才会发送真正的请求

Click有300ms延迟原因及如何解决?

​ 移动端触发按照touchstart、touchmove、touchend、click顺序触发;触发touchend,click之间会有200-400不等的时间延迟,移动端要判断用户是否想要进行双击

解决:

(1)禁止缩放: meta标签

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

(2)FastClick库, 检测到touchend事件时,会通过DOM自定义时间立即触发一个模拟click事件的click事件,并阻止300ms之后真正触发的点击事件

window.addEventListener("load",function(){
	FastClick.attch(document.body);
},false);

移动端1px解决方案

移动端css里面写了1px, 实际看起来比1px粗

1px变粗的原因: viewport的设置和屏幕物理分辨率是按比例而不是相同的.

XSS攻击和CSRF攻击?防御方法?

1) XSS(Cross Site Scripting):跨域脚本攻击。XSS攻击的核心原理是:不需要你做任何的登录认证,它会通过合法的操作(比如在url中输入、在评论框中输入),向你的页面注入脚本(可能是js、hmtl代码块等)。

最后导致的结果可能是:盗用Cookie 破坏页面的正常结构,插入广告等恶意内容 ;D-doss攻击

XSS的防范措施主要有三个:

  • 编码:

对用户输入的数据进行 HTML Entity 编码。Encode的作用是将字符进行转化,使得浏览器在最终输出结果上是一样的。

  • 过滤

移除用户输入的和事件相关的属性。如onerror可以自动触发攻击,还有onclick等。移除用户输入的Style节点、Script节点、Iframe节点。(尤其是Script节点,它可是支持跨域的呀,一定要移除)。

  • 校正

避免直接对HTML Entity进行解码。使用DOM Parse转换,校正不配对的DOM标签。

2)CSRF(Cross-site request forgery):跨站请求伪造

用户是网站A的注册用户,且登录进去,于是网站A就给用户下发cookie。

要完成一次CSRF攻击,受害者必须满足两个必要的条件:

(1)****登录受信任网站A,并在本地生成Cookie****。(如果用户没有登录网站A,那么网站B在诱导的时候,请求网站A的api接口时,会提示你登录)

(2)****在不登出A的情况下,访问危险网站B****(其实是利用了网站A的漏洞)。

温馨提示一下,cookie保证了用户可以处于登录状态,但网站B其实拿不到 cookie。

防御方法:

法一、Token 验证:(用的最多)

服务器发送给客户端一个token;客户端提交表单中带着这个token。如果这个 token 不合法,那么服务器拒绝这个请求。

法二:隐藏令牌: 把 token 隐藏在 http 的 head头中。

法三、Referer 验证:Referer 指的是页面请求来源。意思是,只接受本站的请求,服务器才做响应;如果不是,就拦截。

区别:

CSRF:需要用户先登录网站A,获取 cookie。 XSS:不需要登录。

CSRF:是利用网站A本身的漏洞,去请求网站A的api。 XSS:是向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容。

MVC和MVVM

MVC 在Controller里面把Model的数据赋值给View

  • Model: 模型对象负责在数据库中存取数据。

  • View: 是依据模型数据创建的 ,处理数据显示

  • Controller :负责从视图读取数据,控制用户输入,并向模型发送数据 (用户交互)

    Controller被设计出来并不是处理数据解析的。1、管理自己的生命周期;2、处理Controller之间的跳转;3、实现Controller容器。这里面根本没有“数据解析”这一项, 于是创建出了一个新的类:ViewModel

    Controller只需要数据解析的结果而不关心过程,所以就相当于VM把“如何解析Model”给封装起来了

MVVM

  • Model view ViewModel 一旦在实现Controller的过程中遇到任何跟Model(或者数据)相关的问题,就找VM

二 、HTML部分

HTML语义化标签的理解:

让页面内容结构化,比如标题、段落标签,便于维护,可读性强

iframe是什么?缺点?

iframe元素会创建包含另外一个文档的内联框架

缺点:阻塞主页面onload时间,不利于SEO(搜索引擎无法解读)

Doctype作用?严格与混杂模式区分?

Doctype声明于文档最前面,告诉浏览器以何种方式渲染页面(严格模式和混杂模式)

严格模式:以该浏览器支持的最高标准运行

混杂模式:模拟老式浏览器

HTML5 和css3 的新属性

  • html5新标签:

    • section 内容区块 article 核心内容 header 区块的头部 footer 底部信息 nav 导航信息 aside:侧边栏
    • 音频和视频标签 audio 和 vedio
    • canvas: 进行图形绘制
  • css3新属性

    ​ transform变形;transform:translate(100px,100px);位移

    ​ transform:scale(0.5.,0.2);缩放

    ​ transform:rotate(30deg);旋转

  • border-radius 圆角设置

块元素和行内元素

  • 行内元素:与其他行内元素并排; 不能设置宽高,默认的宽度就是文字的宽度(font , span, b , i , u, sub, sup, a ,)
  • 块级元素: 霸占一行,不能与其他任何元素并列。能接受宽高,如果不设置宽度,那么宽度将默认变为父级的100%。(div, h1-h6 , p ,ul,li,ol, dl,dt, hr,form,table ,tr,td)

BFC

BFC就是块级格式化上下文(不受外边元素影响)

触发

  • float的值不是none。
  • position为absolute和fixed
  • display为 inline-block、table-cell、flex、table-caption或者inline-flex
  • overflow为auto(滚动条)或hidden

应用

  • 防止margin重叠,把后面一个元素放在div里,设置overflow:hidden
  • BFC的区域不会与float box重叠 ,可以完成自适应两列布局

DOM

文档对象类型: 是为HTML和XML提供的API

  • getElementById() 、getElementsByTagName() 、getElementsByClassName() 其中getElementsByTagName() 和 getElementsByClassName() 这两种方法因为其访问的是节点中的可能为复数的属性,所以得到的会是一个以数组的形式

  • DOM事件

    ​ onclick事件—当用户点击时执行 onload事件—当用户进入时执行

    ​ onunload事件—用用户离开时执行 onmouseover事件—当用户鼠标指针移入时执行


三 、 CSS部分

CSS盒模型

1)W3C标准盒子(content-box):又称内容盒子,是指块元素box-sizing属性为content-box的盒模型。它的width是内容的宽度

2)IE盒子(border-box):又称怪异盒模型,是指块元素box-sizing属性为border-box的盒模型。它的width是content + padding + border

link标签 和@import 标签的区别

  • link 是 HTML 文件中的标签,在 标签中引入 CSS 文件。
  • @import 是 CSS 中的一个 @规则,只能出现在 CSS 文件中或 HTML文件的

display:none 和visibility:hidden的区别

  • display:none 后元素不占据空间,而visibility:hidden后元素仍然占据空间
  • display:none 会有回流(即重排), 但是visibility:hidden不会有回流
  • visibility有继承性,子元素会继承父元素属性

position属性值

  • static: 默认值,在正常文档流
  • relative: 相对定位,相对自身元素定位,脱离文档流但仍然占据原来的位置
  • absolute:绝对定位, 以有定位的祖先元素为准,脱离文档流且不占据原来位置、
  • fixed: 固定定位,相对于浏览器窗口,脱离文档流且不占据原来位置

隐藏页面中元素的方法

  • opacity:0 ; (通过设置透明度)
  • visibility:hidden; (元素仍然占据位置)
  • display:none; (元素不占据空间)
  • position: absolute; (再设置left top -999px移出可视区)

css选择器有哪些?优先级

标签,类,ID,全局(*)、后代、伪类、子选择器(>)、

  • 通配符(*) 0
  • 标签、伪元素 1
  • 类、伪类、属性 10
  • ID选择器 100
  • 行内样式 1000
  • !important 无穷大 一旦设置了 !important,那么源代码次序即使是在后面,也不会起效果 层叠顺序就会乱了套,在大型项目中往往会出现很多不可预期的错误。

css实现三角形

首先width和height设置为0,其次,如果想要上三角,则设置下、左、右的 如

border-top:transparent;

弹框的实现

点击弹出框按钮,背景色变为灰色
(1)在原页面基础上添加两个层,一个是弹出层,一个是遮罩层。这两个div先设置display:none让其不显示,然后通过按钮绑定事件实现显示和隐藏。 (XX.style.display = “block”)
(2)设置弹出层的显示大小

width: 200px;
height: 200px;
position:fixed;
top:50%;
left:50%;
transform:translateX(-50%) translateY(-50%);

(3)使用z-index属性设置背景层和弹出层的上下位置,值越大越靠上显示;
(4)设置背景层的透明度

盒子水平垂直居中

  • 定位(三种)
    • 子绝父相,子元素设置 top,left 为50% ,margin-left,margin-top 分别为宽和高的一半(负值)
    • top,left,right,bottom 都为0 ,margin: auto (宽高必须已知)
    • 子绝父相,子元素设置 top,left 为50% ,transform : translate(-50%,-50%)
  • 父元素设置display: flex ; justify-content:center; align-items:center;
  • JS中 (屏幕宽高clientWidth - 元素宽高offsetWidth)/2 px 分别为left和top

清除浮动的方法

  • 额外标签法 加上空的子div标签(相当于占位)
  • 父级添加overflow:hidden
  • 父级设置高度
  • 父级添加after伪元素
.parent:after{
   content:"";  display:block;   height:0;    clear:both;    visibility:hidden;
}
  • 父级添加双伪元素 before after
.parent:before,.clearfix:after{
	content:"";    display:table   (表格,可放在一行)
}
.parent:after{
	clear:both;
}

左右固定,中间自适应布局

  • 自身浮动法

    1. 左右分别使用左浮动 float:left和右浮动float:right使其脱离文档流
    2. 中间的div放在最后占据文档流位置,设置margin-left 和 margin-right
    
  • 绝对定位法

    1.左右设置absolute,父元素设置relative      
    2.左边设置top:0px; left:0px;  右边:top:0px; right:0px; 
    3.中间的div设置margin-left和margin-right
    
  • flex布局

    1.父级元素设置: display:flex    
    2.中间div设置  flex:1
    ==center元素一定要放在中间==
    
  • 圣杯布局(浮动和父margin)

    1.三个元素设置position:relative,float: left
    2.左右设置magin-left (负值)  
    

Flex布局

flex容器有两根轴:水平主轴就是x轴(main axis)和竖直轴也是y轴(cross axis)

Flex布局有两层,采用flex布局的元素称为flex容器,其子元素则自动成flex item,即项目.

flex:是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto

( flex-grow:定义项目的放大比例 ; flex-shrink:定义了项目的缩小比例 , flex-basis:定义了在分配多余空间之前,项目占据的主轴空间 )

弹性布局常用属性

  • display : flex (弹性布局,父级)
  • justify-content (水平对齐,父级)
  • align-items (垂直对齐,父级,不换行无效,用于修改flex-wrap)
  • flex-wrap (换行,父级)
  • align-self (垂直对齐,子级)
  • flex-basis , flex-shrink, flex-grow

四、JS部分

JS的数据类型

  • 基本数据类型: number、string、boolean、undefined、null (不可以添加属性和方法,赋值是简单的赋值,比较是值的比较)
  • 引用数据类型:Object、array、function、data

JS判断数据类型

  • typeof (返回值: number、string、boolean、object、function、undefined、(symbol))

    typeof null //结果为object(二进制前三位是0表示对象)             typeof  undefined   //结果为undefined
    
    
  • instanceof (判断是不是实例,检测的是原型,检测原型链中是否有类型的原型,返回值为true和false)

  • constructor (函数定义时,会自动添上prototype原型,再给prototype上添加一个constructor属性,并让其指向F的引用,就是此函数利用原型对象的constructor属性引用了自身)

    true.constructor == Boolean     new Function().constructor == Function 
    
    
  • Object.prototype.toString.call() (toString()是Object原型的方法。调用此方法,默认返回当前对象的class(对于object对象可以直接返回[object object],而其他类型需要call和apply调用才能正确返回类型))

Object.prototype.toString({a:1})           //[Object  Object]
object.prototype.toString.call([])         //[Object Array]

JS判断是否为数组

  • instanceof判断 a instanceog Array; (当有多个全局环境就不行,如iframe会产生新的全局环境)
  • a.constructor === Array; //(当有多个全局环境就不行,如iframe会产生新的全局环境)
  • Object.prototype.toString().call()可以获取到对象的不同类型,多个全局环境也适用
  • 对于多全局环境,Array.isArray() 同样能准确判断

JS中的类数组和数组

  • 类数组: 拥有length属性 ,不具有数组所具有的方法; 常见的类数组有 arguments对象和 DOM方法的返回结果。比如 document.getElementsByTagName()
  • args = Array.prototype.slice.call(arguments); 将类数组转化为数组

for…循环遍历的方法

  • for循环

  • for in 方法 :for(let i in obj)主要用于遍历普通对象,i 代表对象的 key 值,obj[i] 代表对应的 value

  • for of 方法 for(let i of arr)

  • Array forEach()循环 (无返回值)

    arr.forEach(function(i,index){
     console.log(i,index)
    })
    
    

数组常用方法

  • Array.map() 将数组中的每个元素调用提供的函数,返回新的数组
  • Array.forEach() 将数组中的每个元素执行提供的函数,没有返回值
  • Array.filter() 将所有元素进行判断,将满足条件的元素作为一个新的数组返回
  • Array.reduce() 所有元素调用返回函数,返回值为结果(传入的值必须是函数类型)如加法计算
  • Array.push() 在数组的后面添加新加元素,此方法改变了数组的长度
  • Array.pop() 在数组后面删除最后一个元素,并返回数组,改变了数组的长度
  • Array.shift() 在数组后面删除第一个元素,并返回数组,改变了数组的长度
  • Array.unshift() 将一个或多个元素添加到数组的开头,并返回新数组的长度
  • Array.isArray() 判断一个对象是不是数组,返回的是布尔值
  • Array.concat() 可以将多个数组拼接成一个数组
  • Array.toString() 将数组转化为字符串
  • Array.join() 给定分隔符,按分隔符分割数组
  • Array.splice(开始位置, 删除的个数,元素)
  • ``let` `arr1 = arr.splice(2, 0 ``'haha'``)    增加
    ``let` `arr2 = arr.splice(2, 3)               删除3个
    ``let` `arr1 = arr.splice(2, 1 ``'haha'``)    替换
    

字符串常用

(1)charAt() 返回某个位置的字符。
(2)concat() 将一个或多个字符串拼接起来,返回拼接后的字符串。该方法不会修改原字符串。
(3)==slice()、substr()、substring()==不会修改字符串本身的值,而是将结果返回。有两个参数时:slice和substring返回下标从第一个参数开始到第二个参数-1结束的子串。substr返回下标从第一个参数开始长度为第二个参数的子串
(4)split() 将字符串分割并返回一个数组
(5)trim() 删除字符串前置以及后缀的所有空格并将结果保存在新的字符串中返回
(6)join将一个数组拼接成字符串并返回该字符串,元素之间以join接收的参数作为分割符(默认是",")

五、ES6部分

ES6常用

  • let const
  • 解构赋值 对赋值运算符的扩展 let [a, b, c] = [1, 2, 3];
  • 模板字符串:用一对反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串。
  • “箭头函数”:函数名=(形参)=>{……}。
  • 展开运算符 (数组赋值) 对象也适用
  • Set结构是类似于数组结构,但是成员都是不重复的值
  • Map结构是键值对集合(Hash结构)

let var const 的区别

const 声明只读常量,一旦声明,常量值不能修改(只针对常量,数组和对象的值可修改,不能修改的是内存地址)
const必须有初始化,不能只定义不赋值
let和var 的区别:
let不存在变量提升 用一作用域下不能重复定义同一名称 有严格的作用域(var 函数作用域,let块级作用域)

let 的暂时性死区

块级作用域内存在let命令 , 形成了封闭作用域。 凡是在声明之前就使用这些变量,就会报错。

set和map区别

Set 对象类似于数组,且成员的值都是唯一的。(用于数组去重)
map是一组键值对的结构,具有极快的查找速度(数据存储)
set(key, value):向字典中添加新元素。get(key):通过键查找特定的数值并返回。has(key):判断字典中是否存在键key。

Promise的理解

  • Promise是一种异步编程(回调地狱)的解决方案,有三种状态,pending(进行中)、resolved(已完成)、rejected(已失败)。当Promise的状态由pending转变为resolved或reject时,会执行相应的方法 。
  • 状态一旦改变,就无法再次改变状态
  • Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数

async、await 和 promise、defer、generator

  • async和await让异步看起来像同步 async function(){ await ----- }
  • async是generator的语法糖,声明一个函数为异步,await等待一个异步方法执行完成
  • defer 和async
    • defer 开始新的线程下载脚本,让执行拥有顺序,并使脚本在文档解析完成后执行
    • async是HTML5新增属性,用于异步下载脚本文件,下载完成后立即执行

promise.all和promise.race区别

  • promise.all : 多个 Promise 任务同时执行,如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果
  • promise.race:(比赛的意思) 多个 Promise 任务同时执行,返回最先执行结束的 Promise 的结果,不管 Promise 结果是成功还是失败

事件循环机制(在promise中)

​ 程序最开始是按代码顺序执行代码的,遇到同步任务,立刻执行;遇到异步任务,则只是调用异步函数发起异步请求。此时,异步任务开始执行异步操作,执行完成后到消息队列中排队。之后就需要查询消息队列中是否有等待的消息。如果有,则按照次序从消息队列中把他放到执行栈中执行。执行完毕后,再从消息队列中获取消息,再执行,不断重复。

先执行同步任务,如果存在异步,将宏任务加入到事件队列中,再判断是否还有微任务存在,如果没有执行下一个宏任务,如果有,执行所有的微任务后,再执行下一个宏任务(事件循环)

​ Promise在初始化时,传入的函数是同步执行的,然后注册 then 回调。注册完之后,继续往下执行同步代码,在这之前,then 中回调不会执行。同步代码块执行完后,才会检测是否有可用的 promise 回调,如果有,那么执行,如果没有,继续下一个事件循环

宏任务和微任务

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,

promise构造函数属于同步,.then属于异步

宏任务:包括整体代码script,setTimeout,setInterval、 I/OUI render

微任务:Promise,process.nextTick

箭头函数与普通函数区别

  • 箭头函数语法上更加简洁属于ES6

  • 箭头函数没有自己的this, this是继承函数所属上下文(使用call、apply都无法改变 )

  • 箭头函数没有类数组arguments,只能通过…arg获取传递的参数集合(数组)

  • 箭头函数不能被当做构造函数(new)执行,因为箭头函数没有prototype

  • 箭头函数的this指向是函数被创建时绑定的

  • this是定义时的上一层作用域的this,注意:对象是不能形成独立的作用域

this 指向问题

1.普通函数:this指向直接调用者,默认为window
2.定时器:this指向window
3.立即执行函数:this指向window
4.对象的方法中:this谁调用,指向谁
5.绑定事件:this谁调用,指向谁
6.==闭包的this 指向全局==(因为闭包不属于对象的方法)

call和apply、bind区别 ( 改变this指向)

都可以改变this的指向

call和apply都为立即调用(都是function原型上的方法),bind返回对应函数,稍后调用(改变this指向)

call调用函数,改变this指向,是逐个传参                          fn.call(obj,10,20,30);     
apply会调用函数,以数组形式(参数固定2个)             fn.apply(obj,[10,20,30]);
bind 不会调用函数,但能改变this指向;   返回值为改造完后的原函数拷贝

深浅拷贝

  • 语法糖Object.assign(拷给谁,原拷贝); 浅拷贝,拷贝的是地址
  • 函数递归实现,复制内存空间(不会影响原来对象) (比如数组:循环实现或者 用slice或concat实现)

说一下闭包及其作用

  • 闭包: 可以访问另一个函数作用域中变量的函数

1)如果想要在外部访问函数里的局部变量,可以让函数return 一个函数即可

2)延伸了变量的作用范围

3)参数和变量不会被垃圾回收机制回收,使得函数中的变量都被保存在内存中

4)缺点:内存泄漏(比如说等待点击事件)

事件委托和事件冒泡

事件委托是利用冒泡阶段的运行机制来实现

事件冒泡:从实际操作的元素 一级一级往上传递,依次触发,直到document为止

​ ( event.stopPropagation() 非标准的IE方式:window.event.cancelBubble=true )

事件委托利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件

事件捕获:从上到下,依次传递

​ 比如我们有100个li,每个li都有相同的click点击事件 , 如果要用事件委托,就会将所有的操作放到 js 程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;

target就可以表示为当前的事件操作的dom

跨域

克服Ajax只能同源使用的限制

(同一域名,不同路径、端口、协议; 2.不同域名)

解决跨域方案:

  • JSONP : 网页通过添加一个script元素,向服务器请求JSON数据,不受同源策略限制(src属性);服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

  • nginx代理:

  • document.domain+iframe(主域相同时使用)

  • CORS(使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是该成功还是失败)

    在响应头中注入Access-control-Allow-origin,发出XMLHttpRequest请求,克服了ajax同源限制

五、面向对象部分

object1 == object2 如何判断

(笨办法:每一项逐一判断)
(1. 封装compare,定义一个布尔值来标志 2.object转化为string(JSON.stringify(a)))

面向对象和面向过程

面向过程是朝着步骤来进行

面向对象OOP:找出对象,写出对象功能:封装,继承,多态

对象的创建

(1)new Object() (2)对象字面量{ } (3)构造函数

new在执行时会做?

(1)在内存中创建一个空对象
(2)让this指向这个新对象
(3)执行构造函数里的代码,给新对象添加属性和方法
(4)返回这个新对象

原型链和作用域链

原型链:
如果当前对象没有这个属性,会向它_ _proto__这个属性指向的所属类上的prototype上查找,如果也没有,会向所属类上的prototype上的proto上查找…一直找到Object为止。
作用域链:
如果当前作用域中没有这个私有变量,会向上级作用域查找,一直找到window为止,如果window也没有,则把变量添加到window属性中。

prototype原型对象,对象原型 (proto)

  • 构造函数都有prototype属性(使方法得到共享)

  • 对象都有–proto–属性 指向构造函数的prototype原型对象

    (原型对象prototype里面的_proto__原型指向的是 Object.prototype)

  • 在_proto__和prototype里都有constructor属性(构造函数本身)

  • object.prototype.–proto-- = null

六、VUE

VUE的生命周期(8个阶段)

  • 创建前 :在beforecreate阶段,VUE实例的挂载元素el和数据对象data都为undefined
  • 创建后:在created阶段,vue实例的数据对象data有了,el还没有
  • 载入前:beforeMount阶段,vue实例的el和data已经初始化,
  • 载入后:mounted阶段,
  • 更新前:beforeUpdate阶段
  • 更新后:updated阶段
  • 销毁前:beforeDestroy阶段
  • 销毁后:destroyed阶段

Data为什么是一个函数?

因为每次调用组件的时候都会重新生成一个对象,如果是一个对象的情况下,data数据会进行复用(因为对象是引用数据类型)而当data是一个函数的时候每次调用就会返回一个新的对象

VUE渲染流程

当某个数据属性被用到时,触发 getter,这个属性就会被作为依赖被 watcher 记录下来。
整个函数被渲染完的时候,每一个被用到的数据属性都会被记录。
相应的数据变动时,例如给它一个新的值,就会触发 setter,通知数据对象对应数据有变化。
此时会通知对应的组件,其数据依赖有所改动,需要重新渲染。
对应的组件再次调动渲染函数,生成 Virtual DOM,实现 DOM 更新。

虚拟DOM和 diff

virtual dom是一个虚拟层,并不正式存在,在DOM的基础上在内存建立了一个抽象层,对于改动会同步到虚拟DOM,最后再批量同步到DOM中

diff算法是直接去比对元素,只做同级比较。vue diff调动patch函数,参数是vnode和oldVnode,分别代表新旧节点。
vue比对节点,当节点元素类型相同,但是className不同,认为是不同类型元素,删除重建

VUE当中的指令

  • v-if:判断是否隐藏
  • v-for:数据循环
  • v-bind:class:绑定一个属性v-model:实现数据双向绑定

VUE的数据响应式(双向绑定原理)

使用数据劫持和订阅发布实现双向绑定 ;数据改变后,视图也会自动更新。 在实例化的过程中,通过Object.defineProperty()添加getter和setter, 对DOM做事件监听,如果DOM发生变化,vue监听到,就会修改相应的data

VUE组件间传值的方式

  • 父组件通过属性的方式向子组件传值,子组件通过 props 来接收
  • 子组件向父组件传值,$emit
  • 兄弟组件之间传值 通过 $emit 和 props 结合的方式

v-if 和 v-show 的区别

v-if和v-show都能实现根据判断条件进行展示的效果
v-if的原理是根据判断条件来动态的进行增删DOM元素(直接销毁和重建DOM)
v-show是根据判断条件来动态的进行显示和隐藏元素 (修改元素的display的css属性)

methods、computed、watch的区别

methods是个方法,执行的时候需要事件来触发
computed是一个计算属性,实时响应,只要data属性发生变化就会触发,methods调用要加(),computed调用的时候不需要加()
watch属性监听,监听属性的变化,当值发生变化执行特定的函数,监听的时候会有两个参数(新值,旧值)

VUE监控属性值变化computed

VUEX

用于管理页面的数据状态(状态管理)

  • state 存放数据
  • mutation 同步数据设置的操作( 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。 )
  • getter 从基本数据(state)派生的数据 (需要缓存的数据保存在这里)
  • action 异步操作
  • module 页面多,模块复杂,可进行模块化状态管理

Keep-alive和动态组件

包裹动态组件时,会缓存不活动的组件实例,用于保留组件状态或避免重新渲染
动态组件: 让多个组件使用同一个挂载点,并动态进行切换(通过保留component元素,动态的绑定它的特性,可以实现动态组件)

vue-router有哪几种导航钩子( 导航守卫 )

全局前置导航钩子 beforeEach和全局后置导航钩子 afterEach

应用:

(1) 路由跳转前或跳转后、进入、离开某一个路由前、后,需要做某些操作,就可以使用路由钩子来监听路由的变化
(2)限制前端页面访问权限(router.beforeEach 在每次路由跳转触发
let token = localStorage.gettem(‘token’) 获取本地没token就跳到login页面 )

1、全局守卫: `router.beforeEach`
2、全局解析守卫: `router.beforeResolve`
3、全局后置钩子: `router.afterEach`
4、路由独享的守卫: `beforeEnter`
5、组件内的守卫: `beforeRouteEnter、beforeRouteUpdate (2.2 新增)、beforeRouteLeave

设计模式

单例模式
是一种常用的软件设计模式,在应用这个模式时,单例对象的类必须保证只有一个实例存在,整个系统只能使用一个对象实例。
优点:不会频繁地创建和销毁对象,浪费系统资源。
使用场景:IO 、数据库连接、Redis 连接等。
观察者模式
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式

观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色;
观察者模式在观察目标和观察者之间建立一个抽象的耦合;
观察者模式支持广播通信;
观察者模式符合开闭原则(对拓展开放,对修改关闭)的要求。

但是,观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值