闭包
-
通过作用域的嵌套,触发计算机的垃圾回收机制(硬盘),将原本的局部变量进化成私有变量的环境,叫闭包
function fn(){ var a = 10; return function(){ a ++ ; console.log(a); } } var f = fn(); f();
-
计算机的垃圾回收机制
- 硬盘:需要删除的数据,不直接删除,而是再是保存在一个临时区域,如果需要继续使用,可以从临时区域取出 - 内存:需要删除的数据,直接删除,不可恢复 - 程序,或代码的执行,默认使用的是内存的垃圾回收
-
关于函数的定义作用域和执行作用域
- 定义函数时的作用域,叫定义作用域
- 执行函数时的作用域,叫执行作用域
- 无论函数在哪执行,都可以在自身内部使用自身定义作用域中的数据
-
闭包的特点
- 可以在作用域外部修改作用域内部的数据
- 连接了作用域内外部的桥梁
- 消耗内存
- 内存泄漏(内存溢出)(低版本浏览器以下)
-
闭包的应用场景
-
事件委托的封装
function eveEnt(child, cb){ return function(eve){ // ... for(var i=0;i<child.length;i++){ if(child[i] === tar){ cb.call(tar); } } } }
-
给一些内置方法的回调函数传参
setTimeout(fn("hello"), 1000); function fn(a){ return function(){ console.log(a) } }
-
循环中的事件内使用循环的变量
for(var i=0;i<ali.length;i++){ (function(i){ ali[i].onclick = function(){ console.log(i); } })(i); }
-
继承
- 继承:让一个不具有某些功能或属性的类或对象,通过某些方式使用另一个具有这些功能或属性的类或对象的功能或属性
var obj1 = {
name:"admin",
show:function(){
console.log(this.name)
}
}
var obj2 = {
name:"root"
}
obj1.show();
obj1.show.call(obj2);
-
构造函数继承(改变this指向继承)
- 简单方便
- 多继承
- 只能继承构造函数内部的属性或方法,无法继承原型身上的属性或方法`
原型继承
原型对象继承
只能继承原型身上的属性或方法,无法继承构造函数身上的属性或方法
function Parent(){ this.name = "admin"; } Parent.prototype.show = function(){ console.log(this.name) } function Child(){ this.name = "root" } // 注意深浅拷贝 // Child.prototype = Parent.prototype; for(let i in Parent.prototype){ Child.prototype[i] = Parent.prototype[i] } Child.prototype.show = function(){ console.log("这是改写之后的show") } var p = new Parent(); p.show(); var c = new Child(); c.show();
原型链继承
- 即能继承构造函数内部的属性或方法,也能继承原型身上的属性或方法
- 不方便传参
function Parent(n){
this.name = n;
}
Parent.prototype.show = function(){
console.log(this.name)
}
function Child(){
}
Child.prototype = new Parent("张四");
var p = new Parent("张三");
p.show();
console.log(p)
var c = new Child();
c.show();
console.log( c )
-
混合继承(组合继承)
- 构造函数继承+原型(对象)继承
- 即能继承构造函数内部的属性或方法,也能继承原型身上的属性或方法
- 麻烦
function Parent(n, s){ this.name = n; this.sex = s; } Parent.prototype.show = function(){ console.log(this.name + "----" + this.sex) } function Child(n, s){ Parent.call(this, n, s); } for(let i in Parent.prototype){ Child.prototype[i] = Parent.prototype[i]; } var p = new Parent("张三", "男"); p.show(); console.log(p) var c = new Child("张四", "男"); c.show(); console.log(c)
-
class的继承
- 封装了构造函数继承+原型链继承
- 使用super关键字继承
- 子类继承了父类,父类相对于子类,叫超类
class Parent{ constructor(n){ this.name = n; } show(){ console.log(this.name); } } class Child extends Parent{ constructor(n){ super(n); } } var p = new Parent("张三"); p.show(); console.log(p); var c = new Child("张四"); c.show(); console.log(c);