前端知识点
- MVVM和MVC的区别
- 什么是Vue生命周期
- 钩子函数触发顺序
- Vue
- Vue优点
- 父子通信,兄弟通信
- 指令
- V-if和V-show区别
- Vue-loader
- Vue-key的作用
- v-modal
- Vue data必须是函数的问题
- Vue slot
- Vue-router
- 多个router-view
- route与router的区别
- 导航守卫
- 懒加载
- ES6
- JavaScript
- 同步与异步的区别
- 事件委托
- 如何改变函数内部的this指针的指向
- 跨域问题
- 垃圾回收和内存管理
- 回收机制方式
- 标记清除:
- 引用计数:
- 内存管理
- JS 继承
- new一个对象的过程
- JS定义对象的四种方式
- JS Promise
- JS async await
- 手写promise
- JS 防抖节流
- JS变量提升
- CSS
MVVM和MVC的区别
MVVM主要解决了MVC中大量的DOM操作带来的问题
MVVM是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应到View上
MVC是比较直观的架构模式,用户操作->View(负责接收用户的输入操作)->Controller(业务逻辑处理)->Model(数据持久化)->View(将结果反馈给View)
什么是Vue生命周期
new Vue在创建的时候需要经过一系列的初始化过程
初始化属性,事件及响应式数据
props,methods,data,computed,watch,provide,inject
并将实例挂载到相应的dom元素上且进行监听
这是一个一系列的过程,在这个过程中也会触发一系列的钩子函数,可自定义
钩子函数触发顺序
{new Vue()}
{initial sth ¥options}
beforecreate
{initial sth}
created
{判断有没有el属性,没有需要用户手动vm.$mount(el)}
{模板编译阶段 ast 解析器 优化器 代码生成器 渲染函数}
beforeMount
{渲染函数=>vnode=>(patch)=>视图}
mounted
{watcher -> 虚拟dom}
beforeUpdate
{模板=>渲染函数=>vnode=>(patch)=>视图}
Updated
beforeDestroy
destroyed
Vue
Vue优点
渐进式,可嵌入到现有的程序里,MVVM,虚拟DOM
父子通信,兄弟通信
数据:props
事件:v-on,emit
兄弟通信,原理类似,创建公共组件BUS
指令
v-if,v-on,v-for
V-if和V-show区别
编译过程:
v-if 是 真正 的 条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-show
的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性display。
编译条件:
v-if 是惰性的:如果在初始渲染时条件为假,则什么也不做。直到条件第一次变为真时,才会开始渲染条件块。v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于
CSS 进行切换。
性能消耗:
v-if有更高的切换消耗。v-show有更高的初始渲染消耗。
应用场景:
v-if适合运行时条件很少改变时使用。v-show适合频繁切换
Vue-loader
解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template,再分别把它们交给对应的 Loader 去处理。
Vue-key的作用
patching过程虚拟dom的比较过程中唯一标识,快速定位
v-modal
input 数据绑定
Vue data必须是函数的问题
组件是复用的,避免数据影响
Vue slot
作用域插槽,子组件数据,重新定义方式和内容,但必须是子组件的数据
Vue-router
this.¥router.go(-1)
this.¥router.push{{ path: ’ ’ + id}}(id是如果有参数需要传的时候)
设置name也可以
params会放在url里 取的时候是this.¥route.params.xxx。要在path最后写 /:xxx
query不会放到url里,取的时候是this.¥route.query.xxx
取的时候都是route不是router
不放到url里会有刷新问题
多个router-view
route与router的区别
router对应new的对象
route对应url里配置的跳转,活跃的路由
导航守卫
beforeEach,可用来判断token
懒加载
()=> import ‘’
到这个路由再去请求
ES6
let class this
JavaScript
同步与异步的区别
"同步模式"就是后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。
"异步模式"则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
异步运行机制如下:
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
事件委托
首先要知道什么是事件冒泡。
页面中一个li被点击,相当于其父元素ul,ul的父元素body,body的父元素都被点击。
既然如此,与其给100个li绑定100个事件,还不如给一个ul绑定一个事件,通过event.target来获取具体被点击的元素。
这就是事件委托。
如何改变函数内部的this指针的指向
1.call和apply会调用函数,并且改变函数内部的this指向
2.call和apply传递的参数不一样,apply必须以数组形式
3.bind不会调用函数,但是会改变函数内部的this指向
跨域问题
正向代理
反向代理
后端增加头
jsonp
垃圾回收和内存管理
回收机制方式
定义和用法:垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。
原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。
垃圾回收策略:标记清除(较为常用)和引用计数。
标记清除:
定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:“离开环境”。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。
到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
引用计数:
定义和用法:引用计数是跟踪记录每个值被引用的次数。
基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。
内存管理
1、什么时候触发垃圾回收?
垃圾回收器周期性运行,如果分配的内存非常多,那么回收工作也会很艰巨,确定垃圾回收时间间隔就变成了一个值得思考的问题。
IE6的垃圾回收是根据内存分配量运行的,当环境中的变量,对象,字符串达到一定数量时触发垃圾回收。垃圾回收器一直处于工作状态,严重影响浏览器性能。
IE7中,垃圾回收器会根据内存分配量与程序占用内存的比例进行动态调整,开始回收工作。
2、合理的GC方案:(1)、遍历所有可访问的对象; (2)、回收已不可访问的对象。
3、GC缺陷:(1)、停止响应其他操作;
4、GC优化策略:(1)、分代回收(Generation GC);(2)、增量GC
闭包等会导致内存溢出
JS 继承
1,原型链继承
prototype = new a()
新实例无法向父类构造函数传参
单一
原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!
2,构造函数继承
function b(){
a.call(this,args)
}
只继承了父类构造函数的属性,没有继承父类原型的属性。
可以继承多个构造函数属性(call多个)。
在子实例中可向父实例传参。
无法实现构造函数的复用。(每次用每次都要重新调用)
每个新实例都有父类构造函数的副本,臃肿。
3,组合继承(原型链+构造函数)
4,extends
new一个对象的过程
1、创建一个空对象
varobj=new Object();
2、设置原型链
obj.proto= Func.prototype;
3、让Func中的this指向obj,并执行Func的函数体。
var result =Func.call(obj);
4、判断Func的返回值类型:
如果是值类型,返回obj。如果是引用类型,就返回这个引用类型的对象。
if (typeof(result) == “object”){
func=result;
}else{
func=obj;;
}
JS定义对象的四种方式
方式一:
通过对象字面量表示法(又称为直接量、原始方式)。
var obj = {name:“moyu”};
方式二:
通过new和构造函数Object()、String()等。
var obj = new Object();
方式三:
自定义一个对象的构造函数,然后实例化对象。
function a(o){
this.name = “moyu”
}
var obj = new a();
方式四:
通过Object.create()
JS Promise
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署。
resolve作用是将Promise对象状态由“未完成”变为“成功”,也就是Pending -> Fulfilled,在异步操作成功时调用,并将异步操作的结果作为参数传递出去;而reject函数则是将Promise对象状态由“未完成”变为“失败”,也就是Pending -> Rejected,在异步操作失败时调用,并将异步操作的结果作为参数传递出去
Promise实例生成后,可用then方法分别指定两种状态回调参数。then 方法可以接受两个回调函数作为参数:
Promise对象状态改为Resolved时调用 (必选)
Promise对象状态改为Rejected时调用 (可选)
function sleep(ms) {
return new Promise(function(resolve, reject) {
setTimeout(resolve, ms);
})
}
sleep(500).then( ()=> console.log("finished"));
1,执行promise里的function内容
2,执行内部定义的回调函数resolve或者reject改变状态
3,执行then中自定义的回调函数
JS async await
async,顾名思义,异步。async函数对 Generator 函数的改进,async 函数必定返回 Promise,我们把所有返回 Promise 的函数都可以认为是异步函数。
await,顾名思义,等待。正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。
手写promise
创建一个JPromise的类,构造函数传入一个立即执行函数,resolve+reject
class JPromise{
constructor(executor){
function resolve(value){
}
function reject(error){
}
try {
executor(resolve,reject);
} catch (error) {
console.log(error);
}
}
}
定义状态的改变,在constructor外面写then,传入成功回调函数和失败回调函数,然后.then()执行
/*
* 定义状态常量
*/
const PENDING = 1;
const FULFILLED = 2;
const REJECTING = 3;
/*
* 定义JPromise构造函数,定义then原型方法
* @params {Function} excutor;函数参数依次是resolve和reject
*
* @return {Object};返回promise实例对象
*/
class JPromise{
constructor(excutor){
const me = this;
me.status = PENDING;
me.value = null;
me.error = null;
function resolve(val){
if(me.status === PENDING){//检查状态,不可逆操作
me.status = FULFILLED;
me.value = val;
}
}
function reject(val){
if(me.status === PENDING){//检查状态,不可逆操作
me.status = REJECTING;
me.error = val;
}
}
try {
excutor(resolve,reject);
} catch (error) {
reject(error);
}
}
then(onResolve,onReject){
const me = this;
if(me.status === FULFILLED){
onResolve(me.value);
}
if(me.status === REJECTING){
onReject(me.error);
}
}
}
运行方法
new JPromise((resolve)=>{
resolve(1);
}).then((res)=>{
console.log(res);
});
还需要存储回调函数,then返回promise等操作,可见链接
参考链接http://www.360doc.com/content/21/0110/19/73323647_956190760.shtml
JS 防抖节流
JS变量提升
var这种变量提升到顶端执行,全局变量会被局部作用域中的同名变量覆盖
CSS