面向对象--闭包 继承
闭包
一、概念及作用
闭包是指在JavaScript中,内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
二、本质
闭包函数:将所在函数作用域中的变量长期驻留在了内存中(内存泄漏)
四、闭包的问题及处理
1.使用全局变量进行累加和
1 var num = 3; 2 function sum(){ 3 num++; 4 } 5 alert(sum()); //undifined 6 alert(sum()); //undifined 7 alert(sum()); //undifined 8 sum(); //num=4; 9 alert(num); //4 10 sum(); //mum = 5; 11 alert(num); //5 12 sum(); //num=6; 13 alert(num); //6
2.1使用局部变量进行累加和
1 function fn(){ 2 var a = 3; 3 return function(){ 4 a++; 5 return a; 6 } 7 } 8 alert(fn()()); //4 9 alert(fn()()); //4 10 alert(fn()()); //4 11 12 var me = fn(); //function(){a=3;a++;return a;} 13 alert(me()); //4 14 alert(me()); //5 15 16 alert(me()); //6
2.2
1 var a = 4 ; 2 function fn(){ 3 var a = 3; 4 return function(){ 5 alert(this.a++); //this指向window 输出4; 6 a++; 7 return a ; 8 } 9 } 10 alert(fn()()); //4 11 12 3.循环里的匿名函数的取值问题 13
3.1
1 function fn(){ 2 var arr=[]; 3 for(var i=0;i<5;i++){ 4 arr[i]=function(){ 5 return [i]; 6 } 7 } 8 return arr; 9 } 10 11 alert(fn()); //五个函数块
3.2
1 function fn(){ 2 var arr = []; 3 for(var i = 0;i<5;i++){ 4 arr[i]=function(){ 5 return i; 6 } 7 } 8 return arr; 9 } 10 var list = fn(); 11 for(var i=0;i<list.length;i++){ 12 alert(list[i]()); //5个5 13 }
3.3
1 2 function fn(){ 3 var arr =[]; 4 for(var i =0 ;i<5;i++){ 5 arr[i]=(function(i){ 6 return i; 7 })(i); 8 } 9 return arr; 10 } 11 var list =fn(); 12 for(var i=0;i<list.length;i++){ 13 alert(list[i]); //0 1 2 3 4 14 }
3.4
1 function fn(){ 2 var arr=[]; 3 for(var i = 0;i<5;i++){ 4 arr[i]=(function(i){ 5 return function(){ 6 return i; 7 } 8 })(i); 9 } 10 return arr; 11 } 12 var list =fn(); 13 for(var i=0;i<list.length;i++){ 14 alert(list[i]()); //0 1 2 3 4 15 16 }
继承
三种继承:经典继承、原型继承、混合继承(重点掌握)------>【call、apply】
一、创建类 ( ES5)
(一)、经典继承
1.构造函数( 父类)
1 function Father(name,age,money){ 2 //实例属性 3 this.name = name; 4 this.age = age; 5 this.money = money; 6 //实例方法 7 this.showName=function(){ 8 return this.name; 9 } 10 this.showAge=function(){ 11 return this.age; 12 } 13 this.showMoney=function(){ 14 return this.money; 15 } 16 17 }
2.子类:只能继承实例
1 function Son(name,age,money,sex){ 2 //经典继承,伪装继承、冒充继承(call,apply)只能继承实例 3 //Father.call(this,name,age,money); 4 //Father.applay(this,[name,age,money]); 5 Father.apply(this,arguments); 6 this.sex=sex; 7 this.showSex=function(){ 8 return this.sex; 9 } 10 11 }
3.测试
1 var son = new Son("李四",12,5000000,"男"); 2 alert(son.showName()); 3 alert(son.showAge()); 4 alert(son.showMoney()); 5 6 alert(son.showSex());
4.call 和 apply的区别(面试题)
相同:a.二者都不能继承原型
b.第一个参数this都一样,指当前对象
不同:
第二个参数不一样:call的是一个个的参数列表;apply的是一个数组(arguments也可以)
(二)、原型继承
1.父类
1 function Father(){} //构造函数 2 //原型属性 3 Father.prototype.name ="李四"; 4 Father.prototype.age=12; 5 //原型方法 6 Father.prototype.showName=function(){ 7 return this.name; 8 } 9 Father.prototype.showAge=function(){ 10 return this.age; 11 }
2.子类
function Son(){};
【3.原型继承】-----------省略
//Son.prototype=Father.prototype; //Son.prototype=new Father();
4.遍历父类原型
1 for(var i in Father.prototype){ 2 Son.prototype[i]=Father.prototype[i]; 3 } 4 var son =new Son(); 5 alert(son.showName()); 6 alert(son.showAge());
(重点)混合继承
[ 1 ]prototype的概念
javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。
1. 父类 function Father(name,age){ //实例属性 this.name=name; this.age=age; } //原型方法 Father.prototype.showName=function(){ return this.name; } Father.prototype.showAge=function(){ return this.age; } 2. 创建一个干爹 function Godfather(name,age,money){ this.money=money; } Godfather.prototype.showMoney=function(){ return this.money; } 3. 子类 function Son(){ //继承实例,经典继承 Father.apply(this,arguments); Godfather.apply(this,arguments); } //原型链继承 for(var i in Father.prototype){ Son.prototype[i]=Father.prototype[i]; } for(var i in Godfather.prototype){ Son.prototype[i]=Godfather.prototype[i]; } var son =new Son("小四",45,6565689); alert(son.showName()); alert(son.showAge()); alert(son.showMoney()); 4.创建一个孙类 function Grandson(name,age,money){ Son.apply(this,arguments); } for(var i in Son.prototype){ Grandson.prototype[i]=Son.prototype[i] } var grandson =new Grandson("李晓武",23,56834534); alert(grandson.showName()); alert(grandson.showAge()); alert(grandson.showMoney());