javascript對象---10 繼承

1、繼承的概念

繼承是面向對象的重要特徵。繼承是指子類對象擁有父類對象的屬性與方法,同時子類對象能夠覆蓋擴展父類對象的屬性和方法。函數

JS中繼承的特色:this

1.子類對象  擁有 父類對象 的 屬性和方法; (把構造函數稱爲一個類,使用構造函數爲當前對象初始化屬性)spa

2.子類對象能夠有本身的新屬性和方法;prototype

3.子類對象能夠重寫父類對象的方法;指針

4.JS中並無專門的繼承語法,但能夠經過原型鏈機制實現。對象

把共有的屬性封裝在父類,子類繼承繼承

繼承的優勢內存

1.提供了一種優良的代碼組合方式,提升了代碼的重用性。原型鏈

2.子類能夠靈活調用父類的屬性,同時能夠擴展覆蓋父類的屬性,體現靈活性。get

3.提供了代碼的可維護性

2、原型繼承方式

原型繼承方式:經過原型鏈完成繼承。任何對象都會經過原型鏈繼承Oject函數的 prototype對象中的屬性和方法

正常聲明兩個構造函數 ---人類 和學生

//人類 : 性別年齡-說話、跑跳
        //人類中包括學生 --有學校 考試
        //注意父類並非專門爲子類服務的,父類也會有相關的事例
            function Person(name,age){
                this.name = name;
                this.age = age;
            }
            
            Person.prototype.sayHello = function(){
                console.log("名字:" +this.name);
            }
            
            //建立學生構造函數
            function Student( name ,age ,school){
                this.name = name;
                this.age = age;
                this.school = school;
            }
           Student.prototype.gotoSchool=function(){
                console.log("去"+this.school+"上學")
            }

讓學生繼承人類的  sayhello( ) ;方法 

    function Person(name,age){
                this.name = name;
                this.age = age;
            }
            
            Person.prototype.sayHello = function(){
                console.log("名字:" +this.name);
            }
            
            //建立學生構造函數
            function Student( name ,age ,school){
                this.name = name;
                this.age = age;
                this.school = school;
            }
            //修改了
            Student.prototype = new Person();   //必須在添加方法前面 
            //new  Person 沒有建立對象引用他,因此棧內存中沒有值
            //Student的原型對象指針指向了 new Person 對象
            
            Student.prototype.gotoSchool=function(){
                console.log("去"+this.school+"上學");
            }
            
            //當前student1具有Person對象裏面屬性方法---任何Student實例具有 person裏的方法
            var student1 = new Student("Shixin",18, "天津理工大學");
            student1.gotoSchool();
            student1.sayHello();

 

Person.prototype.category="哺乳類";

    console.log(student1.category);    //哺乳類
            student1.category = "靈長類";  //
            console.log(student1.category);   //靈長類
            var student2 = new Student("lis",20, "天津理工大學");
            console.log(student2.category);   //哺乳類

//添加設置,返回方法

Person.prototype.setCategory = function( val){
                this.category = val;
            }
            
            person.prototype.getCategory = function(){
                return  this.category;
            }

 

    student1.setCategory("靈長類");    
            console.log(student1.getCategory()); ----------//靈長類
            
            var student2 = new Student("lis",20, "天津理工大學");
             console.log(student2.getCategory()); ----------------//哺乳類

 

缺點:

1.原型對象中數據發生變化,會致使多有對象數據都變化

2.沒法向父類·對象·傳遞參數。

3、構造函數繼承方式

經過構造函數完成繼承

缺點:只能繼承父類構造函數中執行的賦值的屬性,沒法對原型對象的屬性進行繼承,所以不多單獨使用

//構造函數的應用場景,只能繼承基本屬性,沒法繼承方法;
            function Person( name,age){
                this.name = name;
                this.age = age;
            }
            
            //子類
            function Student( name,age,schoolName){
                this.schoolName = schoolName;
                Person.call(this,name,age);    //繼承基本屬性 ---賦值 name age
            }
            Student.prototype.goToSchool = function(){
                console.log("去"+this.schoolName+"上學");
            }
            
            var st = new Student('張三',18,"理工大學");
            st.goToSchool();

結果:----去理工大學上學

4、混合繼承方式

經過構造函數,原型鏈共同完成繼承,使用最多的方案

 function Person( name,age){
                this.name = name;
                this.age = age;
            }
             Person.prototype.sayHello = function(){
                 console.log("我叫"+this.name);
             }
             function Student ( name, age,schoolName){
                 this.schoolName = schoolName;
                 Person.call(this,name,age);    //構造函數繼承方式--this值加到 建立的對象上,student

至關於進行了 this.name=name,this.age=age;
             }
             Student.prototype = new Person(); //重置原型鏈可使用Person()的方法
             Student.prototype.gotoSchool = function(){
                 console.log("我去"+this.schoolName+"上學");
             }
             var student = new Student("張三",18,"理工大學");
             student.sayHello();
             student.gotoSchool();

我叫張三
我去理工大學上學

缺點: 調用兩次Person構造函數 

1次-Student.prototype = new Person(); 只是原型鏈改變

2次--  Person.call(this,name,age);

爲了解決這個弊端採用下種方法

5、寄生組合繼承方法 --最優良

寄生組合繼承方式:將子對象的prototype 設定爲克隆出來的父類的 prototype 對象。最優的解決方案。

經過本身構建一個prototype --- 替換 Student.prototype = new Person();

  Student.prototype = new Person(); // 只須要借用原型鏈不須要執行代碼 

new person()的過程

1.建立內存空間

2.改變this指向

3.原型鏈指定

4.執行函數體

前3步須要,最後一步不須要

1.  var ob = new Object();

2. ob.constructor = Student;

3 .ob.prototype = Person; 原型鏈指向Person

爲了避免打亂原型鏈 --提出一個公用方法

function inherit( parent, child){ //父親孩子

}  

 

//寄生組合方式
            function inherit( parent,child){                  //建立一個深度克隆 父類 prototype對象                   var prototype = Object( parent.prototype); //至關於又複製了一個內存空間                 //改變這個protityoe對象的 構造指針constructor指針指向子類的構造函數。                 prototype.constructor = child;                 //修改child的指針                 child.prototype =  prototype             }                          function Person( name,age){                 this.name = name;                 this.age = age;             }             Person.prototype.sayHello  = function(){                 Console.log("名字:" +this.name);             }                          function Student(name,age,schoolName){                 this.schoolName = schoolName;                 Person.call(this,name,age);             }                          inherit(Person,Student);             Student.prototype.gotoSchool = function(){                 console.log("去" + this.schoolName +"上學");             }

相關文章
相關標籤/搜索