面向对象--闭包 继承

时间:2021-02-03 22:38:45
闭包
 
一、概念及作用
 
        闭包是指在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());