JavaScript中OOP——>>>面向对象中的继承/闭包

时间:2023-01-07 19:47:56

  前  言

 OOP 

 JavaScript中OOP——>>>面向对象中的继承/闭包

 

1.1面向对象的概念

  
  使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方法。
      >>> 继承的两方,发生在两个类之间。

 

1.2JS模拟实现继承的三种方式:

         首先,了解一下call/apply/binb:通过函数名调用方法,强行将函数中的this指向某个对象;
            call写法:  func.call(func的this指向的obj,参数1,参数2...);
            apply写法:  func.apply(func的this指向的obj,[参数1,参数2...]);
              binb写法:  func.binb(func的this指向的obj)(参数1,参数2...);
         
           call与apply的唯一区别:在于接收func函数的参数方式不同。call采用直接写多个参数的方式,而apply采用是一个数组封装所有参数。
        

   ① 扩展Object实现继承
             1:定义父类
                     function Parent(){}
             2:定义子类
                    funtion Son(){}
             3:通过原型给Object对象添加一个扩展方法。
                    Object.prototype.customExtend = function(parObj){
                        for(var i in parObj){
                            // 通过for-in循环,把父类的所有属性方法,赋值给自己
                               this[i] = parObj[i];
                        }
                    }
              4:子类对象调用扩展方法
                      Son.customExtend(Parent);

 

① eg:
 1     // 1.定义父类
 2         function Person(name,age){
 3             this.name = name;
 4             this.age = age;
 5             this.say = function(){
 6                 alert(this.name+":"+this.age);
 7             }
 8         }
 9         // 2.定义子类
10         function Student(no){
11             this.no = no;
12             this.add = function(a,b){
13                 alert(a+b);
14             }
15         }
16         function Programmer(lang){
17             this.lang = lang;
18             this.codding = function(){
19                 alert("我爱敲代码!敲代码使我快乐!");
20             }
21         }
22         // 3.通过原型给Object对象添加一个扩展方法。
23         Object.prototype.customExtend = function(parObj){
24             for(var i in parObj){ 
25                 // 通过for-in循环,把父类的所有属性方法,赋值给自己
26                    this[i] = parObj[i];
27             }
28         }
29         
30         var p = new Person("小明","18");
31         var s = new Student("0001");
32         s.customExtend(p);//现在s继承了p的所有属性和方法。
33         console.log(s)
34         
35         var pro = new Programmer("JavaScript");
36         pro.customExtend(p);
37         console.log(pro)
38         
39 
40         
41         

 

 

  
    ② 使用call/apply/binb.
                1:定义父类
                    funtion Parent(””,””,””){}
                2:定义子类
                    function Son(””,””,””){}
                3:在子类中通过call方法/apply/binb方法去调用父类。
                    function Son(){
                        Parent.call(this,””,””,””);// Parent.apply(this,[””,””,””]);//Parent.binb(this)(””,””,””);
                    }

 

② eg:

 

 1         function Person(name,age){
 2             this.name = name;
 3             this.age = age;
 4             this.say = function(){
 5                 alert("我叫:"+this.name+";今年:"+this.age+"岁");
 6             }
 7         }
 8         
 9         /** 文档注释,调用函数时,可以看到注释内容。
10          * 
11          * no:学员编号
12          * stuName:学员姓名
13          * stuAge:学员年龄
14          */
15         function Student(no,stuName,stuAge){
16             
17             this.no = no;
18             Person.call(this,stuName,stuAge);
19             // 执行上述代码,相当于将下面的代码执行一遍。并且把原来Person类的this直接替换为Stundet的this(当实例化Student时的那个对象)
20             
21 //            this.name = "张三";
22 //            this.age = 14;
23 //            this.say = function(){
24 //                alert("我叫:"+this.name+";今年:"+this.age+"岁");
25 //            }
26         }
27         
28         var stu = new Student(12,"zhangsan",14);
29         stu.say();
30         
31         console.log(stu)
32         
33         //Person("zhangsan","123");

 

    
   ③ 使用原型继承
                1:定义父类
                   function Parent(””,””,””){}
                2:定义子类
                   function Son(””,””,””){}
                3:把在子类对象的原型对象声明为父类的实例。
                   Son.prototype = new Parent(””,””,””);

 

③ eg:

 

 1         function Person(name,age){
 2             this.name = name;
 3             this.age = age;
 4             this.say = function(){
 5                 alert("我叫:"+this.name+";今年:"+this.age+"岁");
 6             }
 7         }
 8         
 9         /** 文档注释,调用函数时,可以看到注释内容。
10          * 
11          * no:学员编号
12          * stuName:学员姓名
13          * stuAge:学员年龄
14          */
15         function Student(no){
16             this.no = no;
17         }
18         
19         Student.prototype = new Person("张三",14)
20         
21         var stu = new Student(12);
22         
23         stu.say();
24         
25         console.log(stu)
26         
27         //Person("zhangsan","123");

 

1.3面向对象中的闭包

  
   1、 全局变量:函数外声明的变量
             局部变量:函数内声明的变量
         
             在JS中,函数为唯一的局部作用域,而if、for等其他{}没有自己的作用域
         
             所以,函数外不能访问局部变量。其实,变量在函数执行完毕以后,占用的内存就被释放。
         
          2、如何访问函数私有变量?
             JS中,提供了一种"闭包"的概念:在函数内部,定义一个子函数,可以用子函数访问父函数的私有变量。执行完操作以后,将子函数通过return返回。
         
                 function func2(){
                    var num = 1;
                    function func3(){
                        var sum = num+10;
                        alert(sum);
                    }
                    return func3;
                }
                
                var f = func2();
                f();
         
          3、闭包的作用:
             ① 访问函数的私有变量;
             ② 让函数的变量始终存在于内存中,而不被释放。