前端基础知识整理

一、JS相关

1、事件模型
原始事件模型(DOM0级)

在原始事件模型中,事件发生后没有传播的概念,没有事件流,事件发生后马上处理。监听函数只是元素的一个属性,通过元素的属性值绑定监听器。
优点:所有浏览器都兼容
缺点:1、逻辑与显示没有分离。2、相同的监听函数只能绑定一个,后绑定的会覆盖前面的。3、无法通过冒泡和委托等机制完成更多得到功能

IE事件模型

IE事件模型共有两个过程,1)事件处理阶段,事件到达目标元素触发目标的监听函数。2)事件冒泡阶段,事件从目标元素冒泡到document,依次检查进过的节点是否绑定了事件的监听函数,如果有则执行
绑定方式:attachEvent(eventType,handler)
移除方式:detacheEvent(eventType,handler)

DOM2级

属于W3C标准的事件模型,现代浏览器都支持,共有3个过程。1)事件捕获:事件从document一直传播到目标元素,依次检查进过的节点是否绑定了事件的监听函数,如果有则执行。2)事件处理:事件到达目标,并触发目标元素上的监听函数。3)事件从目标元素冒泡到document,依次检查进过的节点是否绑定了事件的监听函数,如果有则执行
绑定方式:addEventListener(eventType,handler,是否捕获)
移除方式:removeEventListener(eventType,handler,是否捕获)

2、let和var的区别

let要先声明再使用
let不允许重复申明
let有块级作用域
let有暂时性死区(在父作用域里定义了一个变量,在子作用域里又定义了一个同名变量,那么在子作用域内的这个变量,在申明前是无法使用的。)

3、箭头函数与普通函数的区别

箭头函数是匿名函数,不能作为构造函数,不可以被new
箭头函数没有argument
箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响

4、函数防抖与函数节流

两者都是为了限制函数的执行频次以优化函数触发频率过高导致的响应速度跟不上而出现的延迟、假死、卡顿等现象
1)、函数防抖:当调用动作过n秒后才会执行该动作,若在n秒内又调用了此动作则会重新计算执行时间。有点类似于做电梯,有人在出发前进入了,就要再等一段时间才会走

function debounce (fn, delay) {
  let timer = null
  return function() {
    let context = this
    let args = arguments
    clearTimeout(timer)
    timer = setTimeout(function(){
      fn.apply(context, args)
    }, delay)
  }
}

2)、预定一个执行周期,当调用动作的时刻大于等于执行周期是=时则执行该动作,然后进行下一个周期。有点类似于乘火车,到点就走

function throttle (fn, throshold) {
  let last
  let timer = null
  throshold || (throshold = 250)
  return function () {
    let context = this
    let args = arguments
    let now = new Date()
    if (last && now < last + throshold) {
      clearTimeout(timer)
      timer = setTimeout(function(){
        last = now
        fn.apply(context, args)
      }, throshold)
    } else {
      last = now
      fn.apply(context, args)
    }
  }
}
5、变量类型判断

typeof: 返回的是字符串,适用于基本数据类型的判断(null除外),无法判断数组
instance:检测一个实例是否属于某个类,但检测时只要当前这个类在实例的原型链上结果都会是true。例如:

[] instance of Array (true)
[] instance of Object (true)

constructor:通过对象的constructor判断,但是在类继承时会出错。
注:判断是否为数组的最准确的方式是:Object.prototype.toString.call()

6、跨域

跨域是由于浏览器的同源策略造成的。不同的协议、域名、端口之间的数据访问都会产生跨域的问题,同源策略的引入主要是为了隔离潜在的恶意文件。解决跨域的方法主要有:
JSONP:由于script标签没有跨域限制,所以可以用来解决跨域的问题,在前端定义好一个回调函数,当后端返回后执行这个回调执行这个回调函数来得到需要的数据。
优点:兼容性好。缺点:只能用get方法(因为加载script文件用的是get方法)

cros:cros的基本思想是使用自定义的http头部,允许浏览器和服务器相互了解对方。一般只需要后端对Access-control-allow-orign进行配置,对于带cookies的,需要前端配置withCredentials为true
优点:支持所有的http请求,缺点:兼容性有问题ie10以上才支持

niginx代理:由于同源策略是浏览器的安全策略,不是https协议的一部分。由服务器调用调用接口只是使用了http协议,不会执行js脚本,不需要同源策略,自然也不会有夸一,所以可以通过niginx配置一个代理服务器来做跳板,从而将请求发到后端

7、new一个对象的过程

将构造函数的作用域赋值给对象(因此this就会指向新的对象)
执行构造函数中的代码从而为新对象添加属性
返回新对象

8、一些常用的正则判断

1、判断是否为电话号码

function isPhone(tel) {
    var regx = /^1[34578]\d{9}$/;
    return regx.test(tel);
}

2、判断是否为邮箱

function isEmail(email) {
    var regx = /^([a-zA-Z0-9_\-])+@([a-zA-Z0-9_\-])+(\.[a-zA-Z0-9_\-])+$/;
    return regx.test(email);
}

3、判断是否为身份证

function isCardNo(number) {
    var regx = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    return regx.test(number);
}

二、CSS相关

1、BFC

BFC块级格式化上下文,一般来说触发了BFC的盒子将成为一个独立的盒子,盒子内的变化不影响到盒子外,具体来说主要有如下特性:
内部盒子会在垂直方向上一个接一个的放置,也就是说父元素完全由子元素撑开,无论是否脱离文档流,可以解决父元素塌陷的问题
垂直方向上的距离由margin决定,不会有外边距合并的问题
不会被浮动元素所覆盖
触发BFC的条件有
浮动元素(float除了none以外的值)
定位元素(position absoult,fixed)
display: flex, inline-block

2、清除浮动的方法

清除浮动是为了解决由于子元素浮动带来的父元素高度塌陷的问题
添加一个新元素并加上clear:both,有点是简单,代码量少。缺点是增加无效的标签不符合语义化的要求
触发BFC
利用after伪元素来在元素内部插入元素块,从而达到清除浮动的效果

父元素:after {
  clear:both;
  content: '',
  display: block;
  height: 0;
  visibility: hidden;
}
3、重绘和回流

重绘是指由于元素外观发生改变时触发的浏览器行为,比如颜色,背景等样式发生改变而进行的重新构造外观的过程。重绘不会引发页面的重新布局

回流是指浏览器为了重新渲染页面的需要,而进行的重新计算元素几何大小、位置的行为。回流可以理解为渲染树需要重新进行计算,一般回流的消耗要比重绘高,所以可以通过添加类的方式而不是直接在DOM上进行修改,在操作某一个元素时使其脱离文档流,这样就不会引起回流了

三、网络相关

四、计算机基础1

1、TCP传输的三次握手和四次挥手
为准确无误的把数据送达目标,TCP采用三次握手
发送端先发送一个带SYN标志的数据包给对方,接收端收到后回传一个带SYN/ACK标志的数据包以示传达的确认信息,最后发送端在回传一个带ACK标志的数据包,代表握手结束。若在握手的过程中某个过程中断,TCP会以相同的顺序发送数据包

断开一个连接需要四次挥手
首先主动关闭方发送一个FIN,用来关闭主动主动方到被动方的数据传输,但是这时主动关闭方任可以接受数据,同时在FIN包之前发送出去的数据,如果没有收到对弈的ACK确认报文,主动关闭方任然会重发这些数据
被动关闭方收到FIN包后发送一个ACK给对方,标识确认收到主动关闭方的FIN包
被动关闭发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送
主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认接收

2、TCP和UDP的区别
TCP是传输控制协议,是基于连接的协议,也就是说,在确认收发数据前必须和对方建立可靠的连接,一个TCP连接要进过3次握手才能建立
UDP是用户数据协议,是面向非连接的协议,它不与对方建立连接,二是直接把数据包发过去。UDP适用于一次只传少量数据,且对可靠性要求不高的环境

3、http缓存
http缓存分为两种,强缓存和协商缓存。强缓存对应的状态码为200。强缓存可以理解成无需验证的缓存。协商缓存对应的状态码为304,是一种无需验证的缓存,一般是缓存到期了而服务器上的文件没有修改可以继续使用

强缓存,响应头里会有expries或者cash-control属性。expries是指缓存到期的时间而cash-control确是由多个字段组成的,像max-age表示的是到期的时间,no-store是禁止缓存。对于expries属性则存在一个问题,由于expries记录的是服务器上的时间,所以用户如果手动修改客户端的时间的话则会使缓存失效

协商缓存,与强缓存类似,协商缓存也有两种选择
last-modify/if-modified-since。last-modify是指最后一次修改的时间,当资源过期后浏览器会发送last-modify给服务器,if-modified-since里写的是last-modify的值,如果发现文件有改变则返回状态码200,如果没有改变则返回304
etag/if-none-match etag类似于文件指纹,在服务器响应请求时,会把etag这个文件唯一标识发给浏览器,在文件过期后,if-none-match会带上etag的值发给服务器,服务器对资源进行比较来决定返回200还是304

4、get和post的区别
get的数据存在url里,post的数据存在body里
由于浏览器对url的长度有限制有限制,传的数据不可超过2k,而post理论上是没有上限的
post在浏览器后退或者刷新时,数据会重新提交而get不会
get会被浏览器缓存,而post不会
get浏览器会把header和data同时发出,服务器响应200。而post则是先发送header,响应100后在发送data
get产生一个数据包,而post有两个

5、http状态码及其含义
100-199:表示请求成功,要求客户端继续提交下一次请求才能完成整个处理过程
200-299:表示成功接受请求,并以完成整个处理过程。常用码为200
300-399:为完成请求客户端需要进一步细化需求
400-499:客户端请求有误
500-599:服务端出现错误

五、vue相关

1、spa单页应用
spa将所有的活动都局限在一个web页面中,仅在该web页面初始化时加载响应的html,js,css。页面加载完后spa不会因为页面的重新加载或者跳转,而是通过js动态的变换html,从而实现用户与UI间的交互
优点:由于避免了页面的重新加载,spa可以提供较为流畅的用户体验,得意与ajax可以实现无跳转刷新
缺点:因为没有一页页的html给搜索引擎爬,SEO不好。同时由于所有文件都在一页上,首屏加载速度较慢

2、vue生命周期
beforecreate
完成实例初始化,初始化非响应式变量
this指向创建的实例;
可以在这加个loading事件
data computed watch methods上的方法和数据均不能访问

created
实例创建完成
完成数据(data props computed)的初始化 导入依赖项。
可访问data computed watch methods上的方法和数据
未挂载DOM,不能访问 e l , el, el,ref为空数组
可在这结束loading,还做一些初始化,实现函数自执行,
可以对data数据进行操作,可进行一些请求,请求不易过多,避免白屏时间太长。
若在此阶段进行的 DOM 操作一定要放在 Vue.nextTick() 的回调函数中

berofeMount
有了el,编译了template|/outerHTML
能找到对应的template,并编译成render函数

mounted
完成创建vm.$el,和双向绑定
完成挂载DOM 和渲染;可在mounted钩子对挂载的dom进行操作
即有了DOM 且完成了双向绑定 可访问DOM节点 $ref
可在这发起后端请求,拿回数据,配合路由钩子做一些事情
可对DOM 进行操作

beforeUpdate
数据更新之前
可在更新前访问现有的DOM,如手动移除添加的事件监听器

updated
完成虚拟DOM的重新渲染和打补丁
组件DOM 已完成更新
可执行依赖的dom 操作
注意:不要在此函数中操作数据,会陷入死循环的

activated
在使用vue-router时有时需要使用来缓存组件状态,这个时候created钩子就不会被重复调用
如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发

deactivated
keep-alive 组件被移除时使用

beforeDestroy
在执行app.$destroy()之前
可做一些删除提示,如:你确认删除XX吗?
可用于销毁定时器,解绑全局时间 销毁插件对象

destroyed
当前组件已被删除,监听事件、组件、事件、子实例也被销毁。这时组件已经没有了,无法操作里面的任何东西了

3、组件通信
简单的数据通信
父传子props,子传父$emit。但对于深层组件嵌套中的数据传递,使用这种方式就需要一层一层的传递并不是很方便
$root
vue提供 r o o t 函 数 , 子 组 件 可 以 直 接 访 问 到 根 组 件 d a t a 上 的 数 据 , 对 于 组 件 量 少 的 应 用 可 以 直 接 使 用 root函数,子组件可以直接访问到根组件data上的数据,对于组件量少的应用可以直接使用 root访data使root来通信,但对于大中型应用就不合适了,这样数据会不易于维护,也不容易追踪数据的变化

BUS总线
通过在vue的原型上挂载一个bus属性,并将这个属性指向已给vue实例,由于每一个组件都是通过vue这个类创建的,所以组件上就都会有bus这个属性,也就实现了组件间的通信。总线方式将原有的数据传输的方式转为事件驱动,这一点规避了组件层嵌套的问题,但开发人员无法跟踪和调试数据

vuex
vuex解决了多个视图依赖于同一个状态,而来自不同视图的行为需要变更同一状态的问题。vuex将数据同一储存在state中,通过mutation改变state中的数据,利用action来进行异步的数据操作,利用modules来讲各模块分开管理

4、jquery和vue的区别
数据和视图分离
jquery数据和视图没有分离。这里以作一个todoList为例,我们在input输入框输入内容后,点击提交按钮后生成一个li,这时数据和视图是没有分离的,li是我们通过js生成的DOM是视图,而li里的文字属于数据。所以这里数据和视图是混合的

而在vue中如果也做一个todoList的话,我们只要在点击时将input里的数据push到li要巡护渲染的数组中,数据和视图是完全分开的,我们操作的实际上只有数据不涉及视图

数据驱动视图
还是以todoList为例,jquery是通过直接修改DOM的形式来完成的,而vue是通过对要进行v-for数组进行修改从而生成DOM,这就是以数据驱动视图,我们只需要关心数据的变化,DOM的操作则被vue内部封装

5、响应式

var obj = {}
var name = 'aaa'
Object.defineProperty(obj, name, {
  get: function() {
    return name
  },
  set: function (newVal) {
    name = newVal
  }
})

这里如果不使用defineProperty的话,obj只是一个静态的值类型是没有什么逻辑的,我们无法得知它在什么时候被读取了,被赋值了。但通过Object.defineProperty,可以在get和set里加上一些逻辑,就可以进行一些操作,比如页面渲染

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值