十八、面向对象
1.特征
封装:就是封装变化,因此封装的作用,就解决了程序的可扩展性。
继承:子类继承父类,可以继承父类的方法及属性
多态:接口的多种不同的实现方式即为多态
2.面对对象编程,分为几个步骤?
它分为面向对象的分析(OOA),面向对象的设计(OOD),面向对象的编程实现(OOP)三个大的步骤。
1、首先是分析需求,先不要思考怎么用程序实现它,先分析需求中稳定不变的客体都是些什么,这些客体之间的关系是什么。
2、把第一步分析出来的需求,通过进一步扩充模型,变成可实现的、符合成本的、模块化的、低耦合高内聚的模型。
3、使用面向对象的实现模型
十九、js如何实现继承
1.call和apply实现继承
1.构造父函数,在符函数中写好属性方法;
2.构造子函数,在子函数中实现call、apply对符函数的继承。Father.call(this,ag1,ag2);Father.apply(this,arguments)
3.子函数实例化赋值给新的变量,执行父函数的方法。
2.Es6中class构造函数继承
1.构造父函数
2.对父函数实例化
3.class children exdents Fathero{
constructor(id){
super(id)
}
}
4.对子函数实例化执行
3.原型链继承
1.构造一个父函数
2.在父函数原型对象中写属性方法,constructor:Father
3.构造一个子函数 将父函数的实例化方法赋值子函数的原型
二十、this
定义:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
总结:
1.在普通函数内部,this的指向是window
2.在方法内部,this的指向是方法的拥有者。
3.在箭头函数内部,this指向是创建箭头函数时所在的环境中的this指向的值。
4.在对象中,this指向当前对象
这里的this指向会发生改变
5.计时器中的this
6.回调函数中的this
7.事件处理函数中的this指向事件的绑定者
二十一、'use strict'
1.全局变量声明时,必须加关键字(var)
正常模式:a = 10; console.log(a) //10
严格模式:a = 10; console.log(a) //a is not defined
2.this无法指向全局对象
正常模式:function fn(){ console.log(this) } //window
严格模式:function fn(){ console.log(this) } //undefined
3.函数内不允许出现重名参数
正常模式:function fn( a,b,b ){ console.log(a,b) }
fn(1,2,3) //1,3
严格模式:function fn( a,b,b ){ }
//报错:Duplicate parameter name not allowed in this context 在此上下文中不允许出现重复的参数名
4 arguments对象不允许被动态改变
正常模式:function fn(a){
a=20;
console.log(a); //20
console.log(arguments[0]); //20
}
fn(10);
严格模式:function fn(a){
a=20;
console.log(a); //20
console.log(arguments[0]); //10
}
fn(10);
5 arguments对象不允许被自调用(递归)
正常模式:function fn(a){
if( a == 1 ){
return 1;
}
return arguments.callee(a-1) + a;
}
fn(3); //6
严格模式:function fn(a){
if( a == 1 ){
return 1;
}
return arguments.callee(a-1) + a;
}
//报错:'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
//报错:"caller","arguments","callee",不能在严格模式下使用
二十二、JSON
概念:JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。
结构:有两种结构,对象和数组。
传递方式:后端->前端 JSON.stringify(data) 前端处理-->JSON.parse(data)
二十三、DOM操作
1.创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2.添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子节点前插入一个新的子节点
3.查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
getElementById() //通过元素Id,唯一性
二十四、new操作符
1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this
二十五、一次完整的HTTP事物是怎样一个过程
流程:
1.域名解析
2.发起TCP的3次握手
3.建立TCP连接后发起http请求
4.服务器端响应http请求,浏览器端得到http代码
5.浏览器端解析html代码,请请求html代码中的资源
6.浏览器对页面进行渲染呈现给用户
二十六、MVC框架
1.MVC是业界广泛接受的一种前端应用框架类型,这种框架把应用分为三个部分:
Model(模型)负责管理数据,大部分业务逻辑应该放在Model中
View(视图)负责渲染用户页面,应该避免在View中涉及业务逻辑
Controller(控制器)负责接受用户输入,根据用户输入调用相应的Model部分逻辑,把产生的数据结果交给View部分,让View渲染出必要的输出
2.MVC框架提出的数据流很理想,用户请求先到达Controller,由Controller调用Model获得数据,然后把数据交给View。但是,在实际框架实现中,总是允许View和Model直接通信
二十七、Vue项目环境搭建
1.检测你电脑环境的node与npm的版本(版本过低需升级)
2.安装webpack npm i webpack -g
3.安装vue的脚手架 npm i vue-cli -g
4.初始化并创建目录 vue init webpack store
5.安装依赖 npm i
6.安装npm i vue-router vue-resource axios -D
7.执行项目 npm start
二十八、Vue路由
1.概念:路由其实就是指向的意思,当我们点击home按钮时,页面中就要显示home的内容,点击login按钮时,页面就显示login的内容,也可以说是一种映射,所有在页面上有两个部分,一个是点击部分,一个是显示部分。
2.路由中有三个基本的概念,route,routes,router。
1.router:它是一个路由,是一个单数,点击Home按钮->Home内容
2.routes:它是一组路由,把每一条路由组合起来,串接起来形成一个数组;[{home按钮=>home内容},{about按钮=>about内容}]
3.router:它是一个机制,相当于一个管理者,来管理所有路由;
4.客户端中的路由原理:实际上就是dom 元素的显示和隐藏。当页面中显示home 内容的时候,about 中的内容全部隐藏,反之也是一样。客户端路由有两种实现方式:基于hash 和基于html5 history api.
二十九、VueX
vuex是一个专门为vue.js设计的集中式状态管理架构。
1.State:单一状态树,也被人做为是唯一数据源。(存储数据)
2.Getter:可以认为是store的计算属性,getter的返回值会根据它的依赖被缓存起来,只有它的依赖发生了改变才会被重新计算。
3.Mutation:更改store的状态的方法就是提交mutatin,这个api类似于一个事件,每个mutation都会有一个字符串的事件类型和一个回调函数,在回调函数中处理状态更改。
4.Action:类似于Mutation,不同的是在Action提交的是mutation,而不是直接变更状态。Action可以包含任意异步的操作
5.module:使用单一状态树,应用所有的状态都会集中到一个比较大对象。当应用比较庞大的时候,store就会变得很臃肿。这时候就可以将story分割成模块module。每个模块都拥有自己的state,getter,mutation,action
三十、Vue生命周期
所有的声明周期钩子都是自动绑定this,因此你可以在钩子函数中对属性和方法进行计算。(不可以使用箭头函数)
1.beforeCreate:在实例化初始之后,数据观测和event/watcher事件配置之前被调用;
2.created:在实例化创建完成之后立即被调用,这个时候,实例化已经完成以下配置:数据监测,属性和方法的运算,watch/event事件的回调。然而,挂载还没开始,$el属性目前不可见。
3.beforeMount:在挂载开始之前被调用:相关的render函数首次被调用;
4.mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
5.beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
6.updata:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
7.activated:keep-alive 组件激活时调用。
8.deactivated:keep-alive 组件停用时调用。
9.beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
10.destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
11.errorCaptured:类型:(err: Error, vm: Component, info: string) => ?boolean
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
三十一、Vue路由传参
1.配置路由 {name:'user',path:'/user/:id',component:user}
2.跳转时对<router-link>进行配置
<router-link to="/user/123" >登录123</router-link>
<router-link to="/user/456?a=1&b=2" >登录456</router-link>
<router-link :to="{path:'/user/456?a=52&b=0'}" >登录456</router-link>
<router-link :to="{name:'user',params:{id:'456'},query:{a:1,b:2}}">登录456</router-link>
3.在user组件中取到传过来的参数
取到user组件的路径{{this.$route.path}}
取到传过来的id{{this.$route.params.id}}
取到传过来的对象{{this.$route.query}}
三十二、Vue双向绑定原理
实现原理:vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
数据劫持:vue是通过Object.defineProperty()来实现数据劫持,其中会有get()和set方法;当读取属性值时,就会触发get()方法,在view中如果数据发生了变化,就会通过Object.defineProperty( )对属性设置一个set函数,当数据改变了就会来触发这个函数;
流程:
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
三十三、虚拟DOM
原理:
Virual DOM是用JS对象记录一个dom节点的副本,当dom发生更改时候,先用虚拟dom进行diff,算出最小差异,然后再修改真实dom。
vue的virtual dom的diff算法是基于snabbdom算法改造而来,与react的diff算法一样仅在同级的vnode间做diff,递归的进行同级vnode的diff,最终实现整个DOM树的更新。
虚拟DOM的缺点:
1. 代码更多,体积更大
2. 内存占用增大
3. 小量的单一的dom修改使用虚拟dom成本反而更高,不如直接修改真实dom快