了解闭包
闭包生成的三个条件
- 在函数 A 内部直接或者间接返回一个函数 B
- B 函数内部使用着 A 函数的私有变量(私有数据)
- A 函数外部有一个变量接受着函数 B
function a (){
//这个num变量就是函数a的私有变量
var num = 100
return function b(){
console.log(num)
}
}
var res = a()
// res 接受的是 a 函数执行以后的返回值
//res 接受的就是函数 a 内部返回的一个复杂数据类型(函数b)
res()
//打印出来的就是 a 函数内部的私有变量 num 的值
闭包的特点(优点缺点并存)
- 延长了变量的生命周期
优点: 因为执行空间不销毁, 变量也没有销毁
缺点: 因为执行空间不销毁, 会一直存在在内存中 - 可以访问函数内部的私有变量
优点: 利用闭包函数可以访问函数内部的私有变量
缺点: 执行空间不会销毁, 会一直存在在内存中 - 保护私有变量
优点: 保护私有变量不被外界访问
缺点: 如果想访问, 必须要利用闭包函数
闭包的缺点会造成内存泄漏,不到万不得已不要用。
继承
继承简单来说就是:当 A 构造函数的属性和方法被 B 构造函数的实例使用了,那么我们就说 B 继承自 A 构造函数
常用的继承方法有四种:原型继承,借用构造函数(call)继承,组合继承,类(class)继承
原型继承:
//父类
function Person(name) {
this.name = name
}
Person.prototype.sayHi = function () {
console.log('hello world')
}
//子类
function Student(age) {
this.age = age
}
//实现student继承person
Student.prototype = new Person('Jack')
var s1 = new Student(18)
console.log(s1)
原型继承的缺点就是:继承的属性在__proto__ 里,当我访问的时候就要去 proto 里面找,自己要用的多个参数在多个位置传递,对于代码的书写和代码的维护和阅读都不是很好。
借用构造函数继承
利用call函数改变this指向达到继承目的。
直接看代码
//父类
function Person(name, gender) {
this.name = name
this.gender = gender
}
Person.prototype.sayHi = function () {
console.log('hello world')
}
//子类
function Student(age, name, gender) {
this.age = age
//这里的 this 指向 的是 Student 的当前实例(s1)
//调用 Person 函数, 把函数内部的 this 指向了 Student 的实例
//利用父类构造函数体, 向子类身上添加成员
Person.call(this, name, gender)
}
var s1 = new Student(18, 'Rose', '男')
console.log(s1)
优缺点:
优点:继承来的属性写在了自己的身上,自己需要用到的两个属性的值, 在一个构造函数的时候传递。
组合继承
//父类构造函数
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function () {
console.log('hello world')
}
//子类构造函数
function Student(gender, name, age) {
this.gender = gender
Person.call(this, name, age)//这里的 this 就是 Student 的实例
}
//s1 的 sayHi 方法是依靠这个原型继承继承下来的
Student.prototype = new Person()
var s1 = new Student('男', 'Jack', 18)
缺点:子类的原型上面本来的方法就没有了,必须要继承以后再添加。
类的语法:class
//准备一个父类
class Person{
constructor(name){
this.name = name
}
//原型上的方法
show(){
console.log('hello world')
}
}
//准备一个子类,一个继承自 Person 的 Student 子类
class Student extends Person {
constructor (age, name) {
super(name)
this.age = age;
}
son(){
console.log('我是 子类的方法')
}
}
var s1 = new Student(18, 'Jack')
console.log(s1)
凭借个人理解写的不是很好,也不是很详细,还是要多学习。