一、面向对象编程
所谓面向对象就是,想做一件事,自己做不到,就去找能够实现这个功能的对象,调用它的方法(传递参数,遵守方法规则)
面向对象编程,是一种编程开发思想
每一个对象都是功能中心,具有明确分工,可以完成接受信息,处理数据,发出信息等任务。
因此,面向对象编程具有灵活,代码可复用,高度模块化等特点,容易维护和开发,比起传统的面向过程编程,更适合多人合作的大型软件项目
面向过程就是,先做什么,然后做什么,再做什么,关注点在于解决问题的过程;
面向对象就是,先找一个对象,让它去做这个事情,关注点在找到能解决问题的对象上。
面向对象是面向过程的封装
面向对象的特性:
封装性:
将功能的具体实现,全部封装到对象的内部,外界使用对象时,只需要关注对象提供的方法如何使用,而不需要关心对象的内部具体实现
继承性:
在JS中,继承就是一个对象没有的属性和方法,另外一个对象由,就拿过来用,实现继承
多态性:
JS是弱类型语言,不支持多态
二、构造函数
是一个函数,可以定义形参,接收实参
作用:进行对象的初始化(为对象添加成员)
在JS中,定义一个构造函数,就相当于自定义一种类型
语法:
定义和普通函数差不多,一般首字母是大写
function Student(形参1,形参2,...) {
this.键(key)= 值
}
构造函数中的this指向调用这个构造函数时new所创建的对象
构造函数的调用:
要配合new关键字调用,没有new相当于是调用普通函数
返回的是当前创建的对象
new做了什么:
1. 创建一个对象
2. 将对象的引用赋值给构造函数中的this
3. 调用构造函数为this添加成员
4. 将this的引用返回
注意:不要手动返回值,如果返回的是基本类型的值,会被忽略,如果返回的是一个引用类型的值,则会替换之前创建的对象
继承:
实现继承:获取到构造函数原型中的成员,添加到自身
一个对象所指向的原型是创建这个对象时,构造函数所指向的原型
原型是一个对象,那么可以遍历这个对象,先判断自身是否有同名的键,如果有就跳过,没有就添加
作用域:
全局变量
局部变量(只有方法体内可以使用)
函数内部可以使用函数外部声明的变量,全部变量在任何地方都可以访问到
词法作用域:
函数一旦声明,作用域就确定好了,函数的作用域只与声明有关,与在哪里调用无关
let、const、var:
能使用const就使用const
不能使用const就使用let
不要使用var
Let:
会有块级(大括号:{ })作用域,
作用域就是声明这个let变量的{ },
有效作用域从let开始到他所在的 }结束
不会进行声明的提升,一定要先声明赋值再使用
Var:
没有块级作用域的概念
会进行声明的提升,将声明提升到当前作用域的最前面
Conts:
定义常量(不能修改的变量),一般在模块中的成员都是常量
基本特性和let一样
声明赋值之后不能再修改
只能在声明的同时进行赋值
常量名称一般全部都是大写
三、原型
系统会为构造函数默认关联一个对象(只要定义了一个构造函数,就会默认有一个对象与之关联),这个对象就是构造函数的原型
于之前对象的操作方式一样:添加成员,删除成员,遍历
通过构造函数.prototype访问原型对象
只有这个构造函数所创建的对象,才可以去访问该构造函数的原型
特性:
1. 通过构造函数的prototype属性访问原型的对象
2. 因为原型是一个对象,所以可以像操作普通对象一样操作原型
操作:
1. 在原型中添加成员
成员一般是行为(方法)
2. 访问原型中的成员
只要是当前构造函数所创建的对象,就能直接访问这个构造函数原型中的成员,也只有这个构造函数的对象可以访问
所有的构造函数都是function的实例(Array 和 Person 和 Date 等都是 Function的实例)
原型链:
任何一个对象,都有原型对象,原型对象本身又是一个对象,所以原型对象也有自己的原型对象,这样一环扣一环就形参了一个链式结构
属性查找原则:
如何获取:
1. 先找自身
2. 如果自身没有就根据__proto__对应的原型去查找
3. 如果没有就找到object.prototype,如果都没有,就是报错
四、this和函数的四种调用模式
1. 函数调用模式
如果一个函数不是一个对象的属性时,就是被当做成一个函数来进行调用的,此时this指向了window
2. 方法调用模式
当一个函数被保存为对象的一个属性时,称之为一个方法,当一个方法被低啊用时,this被绑定到当前的对象
3. 构造函数调用模式
如果函数是通过new关键字进行调用的,此时this被绑定到创建出来的新对象上
4. 上下文低啊用模式(借用方法模式)
(1) call
call方法可以调用一个函数,并且可以指定这个函数的this指向
(2) apply
apply()方法接收的是一个包含多个参数的数组,而call()方法接收的是若干参数的列表
(3) bind方法
bind()方法创建一个新的函数,可以绑定新的函数的this指向
This的指向:
单独使用,this指向全局对象
函数中的this指向全局对象
在函数内部,this的指向在函数定义的时候是不能确定的,只有函数执行的时候才能确定
在方法中,this指向调用该方法的对象
五、箭头函数
语法:
let 变量 = (参数) => { }
箭头函数是不能单独使用的
注:
1. 如果函数体只有一句,那么可以省略{},同时默认返回函数体的结构,不能写return
let 变量 = (参数) => ...
2.如果只有一个参数,()可以省略
let 变量 = 参数 => 参数 + 10
4. 如果没有参数,()不能省略
let 变量 = () => ...
特性:
箭头函数的this是确定的,并且永远不变
箭头函数中的this指向创建这个箭头函数所在对象的上下文
六、Es6 class
JavaScript 语言中,生成实例对象的传统方法是通过构造函数,es6的class 的出现 基本上可以替代了es5的构造函数和原型,使之代码结构上更加简洁。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
语法:class Person {
要添加构造器,来为对象进行成员的初始化
constructor(参数1,参数2,...){
this.键(key)= 值
}
Say(){
}在原型中添加成员,可以直接写函数
}
Class继承:class可以通过extends关键字实现继承
语法:
Class 子类 extends 父类
有了extends关键字,子类默认就会继承父类的所有原型中的成员,同时,默认也会继承父类的构造器
class Student extends Person {
Constructor ( name ,age , gender) {
使用this之前必须调用父类构造器,同时让父类构造器中的this为当前子类对象,所以可以通过super关键字来调用父类构造器来构建子类对象的成员
super (name , age)←这句就相当于了(this.name = name, this.age=age)
This.gender = geender
}
}
七、递归函数
函数内部直接或者间接的调用自己
要求:
1. 函数自己直接或间接的调用自己
2. 要有结束条件
斐波那契数列
八、简便的方法
8.1函数参数默认值
定义函数的同时,可以给形参一个默认值,默认值参数一般在参数列表的最后
如果电泳函数的时候没有传递参数,则使用默认值
如果调用函数时传递了参数,则使用传递的参数
Function init(a,b){ }
Function init(b, a = ‘ 有德 ’ ) { }
8.2对象简写
在定义对象的时候,如果属性名和变量名一致,那么可以实现简写
Let name = ‘ 有德 ’
Let age = 20
Let obj = {
‘ name ‘ = name ,
‘ age ‘ = age
}
键值同名简写:
Let obj = {
name,
age
}
8.3解构
从对象或者数组中提取元素
数组结构需要将接收值的变量使用 [ ]包裹
Let arr = [ 1 , 23 , 45 , 78 ]
Let [ a , b , c , d ] = arr
a = 1 b = 23 c = 45 d = 78
注:用 ... 表示剩余的元素,必须放在数组的最后,不能结构出中间的元素
对象结构同理
Let obj = { name : ‘ 有德 ’ ,age :20 , gender : ‘ 男 ’}
Let { name , age} = obj
Name = ‘ 有德 ’ age = 20
注:对象解构的时候,只能解构出对象中已有属性,如果结构的名称在对象中不存,则返回undefined
如果在结构的时候,已有同名变量,可以设置别名,后续使用,是使用别名
Let name = ‘ 马沙 ’
Let age = 20
Let obj = { name : ‘ 有德 ’ ,age :20 , gender : ‘ 男 ’}
Let { name:newName , age:newAge } = obj
newName = ‘ 有德 ’ newAge = 20
如果对象里的成员是对象,也可以二次结构
Let obj = { name : ‘ 有德 ’ ,age :20 , gender : ‘ 男 ’ computer : {
gundam: ‘ 隆巴纳 ’
}
}
Let { computer { gundam } } = obj
获取数组中的元素
元素交换顺序
获取对象中的属性
8.4拓展(展开)运算符 ||剩余运算符
通过 ... 符号来获取剩下的参数
九、Set
不会有重复元素的对象(数组)
十、闭包
在JavaScript中,在函数中可以嵌套定义另外一个函数时,如果内部的函数引用了外部的函数的变量,则产生闭包。
闭包就是一个具有封闭的对外不公外的包裹结构或空间
产生闭包的条件:
当内部函数访问了外部函数的变量的时候,就会形成闭包
1. 函数内部声明函数——嵌套函数——内部函数
2. 内部声明的函数使用了外部声明的成员
3. 返回了内部函数,外面进行接收,通过这个函数使用内部成员
作用:
保护私有变量不被修改
斐波那契数列优化
缓存:数据的缓冲区,当要读取数据时,先从缓冲中获取数据,如果找到,直接获取,如果找不到,重新去请求数据
计算斐波那契数列,会有很大的性能问题,因为重复的计算了很多次,使用缓存来解决性能问题
步骤:
如果要获取数据,先查询缓存,如果有就直接使用,如果没有,就进行计算,斐波那契并且将计算后的结果放到缓存中,方便下次使用
使用缓存,需要保证缓存的数据安全,不能被别人修改,需使用闭包来实现缓存的私有化