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 +"上学");             }

相关文章
相关标签/搜索