闭包
- 闭包:作用域嵌套产生的应用场景
- 特点:大函数嵌套小函数,小函数使用大函数中的变量,大函数就形成了闭包
- 闭包生成的三个直接条件(缺一不可)
1.在函数A内部直接或者间接返回一个函数B
2.函数B内部使用函数A的私有变量(私有数据)
3.函数A外部有一个变量接收函数B
eg:
function A() {
var num = 100;
return function B() {
console.log(num);
}
}
var result = A();
result(); //100
优点
1.作用域空间不销毁,延长了变量的声明周期
2.在函数外部可以访问函数内部的变量
3.保护私有变量,将变量定义在函数内,不会污染全局
缺点
滥用闭包的话,容易造成内存溢出/内存泄漏
继承
两个构造函数之间的关系
当A构造函数的属性和方法能被B构造函数的实例使用了,那么我们就说B继承自A构造函数
==A是B构造函数的父类
==B是A构造函数的子类
原型继承
就是通过改变原型链的方式来达到继承
语法:子类.prototype = 父类的实例
==将子类的原型变成父类的实例对象
//创建父类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log('hello world')
}
//创建子类
function Student(sex) {
this.sex = sex;
}
//将子类的原型变成父类的实例对象
Student.prototype = new Person('zhangsan', 18);
//子类的原型上的添加的属性要放在后面写
Student.prototype.eat = function () {
console.log('能吃')
}
var s = new Student('女');
console.log(s)
原型继承的缺点:
1.继承下来的属性没有继承在自己身上, 在原型上
2.要在多出传参, 对于代码的书写和代码的维护和阅读都不是很好
3.子类定义方法的代码要写在原型继承的后面
借用构造函数继承(借用继承/call继承)
- 继承方案
== 在子类的构造函数体内,借用父类的构造函数执行一下
== 并且强行让父类的函数里面的this指向子类的实例
//创建父类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log('hello world')
}
//创建子类
function Student(sex, name, age) {
this.sex = sex;
//让父类的函数里面的this指向子类的实例
Person.call(this, name, age)
}
Student.prototype.eat = function () {
console.log('能吃')
}
var s = new Student('女', '张三', 17);
console.log(s)
借用继承的优缺点:
+ 优点
1 继承来的属性写在了自己身上, 就不需要去__proto__上找了
2 自己需要用到的两个属性的值,在一个构造函数里面传递, 不像原型继承需要在两个地方传递参数
+ 缺点
只能继承父类的属性
== 不能继承父类原型(prototype)上的方法
== 写在构造函数内的都可以继承下来
组合继承
原型继承 +借用构造函数继承
==利用借用构造函数集合把属性继承在自己身上
==利用原型继承把父类prototype上的方法继承下来
//父类的构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log('hello world')
}
//子类的构造函数
function Student(sex,name,age) {
this.sex = sex;
// 借用继承
Person.call(this,name,age)
}
//原型继承
Student.prototype = new Person();
Student.prototype.eat = function () {
console.log('能吃')
}
var s = new Student('女','张三',18);
console.log(s)
es6的继承语法:
1 书写子类的时候
class 子类 extends 父类
2 在子类的constructor里面书写
super()
来完成继承(相当于在借用父类的构造函数)
//父类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() {
console.log('hello world')
}
}
//子类
class Student extends Person {
constructor(sex, name, age) {
super(name, age)
this.sex = sex;
}
eat() {
console.log('能吃')
}
}
var s = new Student('女', '张三', 18);
console.log(s)