17 原型链和继承

在这里插入图片描述
通过构造函数Person产生的对象,产生的对象没有共用方法

缺点:产生一个对象,就会产生一个方法 ,增加了内存的开销;

//创建构造函数
function Person(name,age){
    this.name=name;
    this.age=age;
    this.show=function(){
        console.log("我叫"+this.name+"我今年"+this.age+"岁")
    }
}
var xiaoming=new Person("小明","18");
var xiaohong=new Person("小红","19");
console.log(xiaoming,xiaohong);
console.log(xiaohong.show===xiaoming.show);//false

解决办法:让对象共用一个方法

因为函数是应用类型,所以将函数提炼到构造函数外部

    //创建构造函数
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.show=show;
    }
    //将函数提炼到构造函数外部
    function show(){
        console.log("我叫"+this.name+"我今年"+this.age+"岁")
    }
    var xiaoming=new Person("小明","18");
    var xiaohong=new Person("小红","19");
    console.log(xiaoming,xiaohong);
    console.log(xiaohong.show===xiaoming.show);//true

新的问题出现:出现了一个全新变量
解决问题:消灭这个全新变量
解决办法:将obj设置为Person的属性

    // Person
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            alert(this.name)
        }
    }
    // Person.obj={
    //     show:function (){
    //         console.log("我叫"+this.name+"我今年"+this.age+"岁")
    //     },
    //     say:function (){
    //         console.log("this is say")
    //     }
    // }
    // 在原型书写
     Person.prototype.show=function (){
                console.log("我叫"+this.name+"我今年"+this.age+"岁")
            }
    Person.prototype.say=function (){
        console.log("this is say")
    }
    var xiaoming=new Person("小明","18");
    var xiaohong=new Person("小红","19");
    console.log(xiaoming,xiaohong);
    console.log(xiaohong.show===xiaoming.show);//true

原型对象
prototype 和** protoconstructor**
通过构造函数访问原型对象: prototype
通过产生的实例访问原型对象: _proto _
通过原型对象访问构造函数:constructor
在这里插入图片描述
原型链
xiaoming这个对象并没有show方法,但却可以调用show方法,属性和方法查找过程为:
1、查找当前对象是否拥有该属性或方法,如果有则直接使用
2、如果没有则去当前对象的原型对象中去查找,如果则使用
3、如果当期对象的原型对象中没有,则去当前对象的原型对象的原型对象去查找,直到最顶级对象
如果有则使用,如果没有属性则为undefined,方法则报错 typeError
综上所述,对象—》原型对象—》原型对象—》…—》最顶级对象,这样就形成了一个链式查找的过程,将这个链称之为原型链 Object.prototype 顶级对象
在这里插入图片描述
关键字

  1. "attr" in obj (检测是否可以通过该对象访问这个属性,值为布尔类型)(true 可以 false 不可以)
    in 就是检测一个对象及其原型链中是否存在该属性
  2. :obj.hasOwnProperty(“attr”) **(检测对象是否有property这个属性)
     // Person
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            alert(this.name)
        }
    }
    var xiaoming=new Person("小明","18");
    //"attr" in obj 检测是否可以通过该对象访问这个属性
	console.log("happy" in xiaoming);//false
    console.log("name" in xiaoming );//true
    //obj.hasOwnProperty("property") 检测对象是否有property这个属性
    console.log(xiaoming.hasOwnProperty("happy"));//false
    console.log(xiaoming.hasOwnProperty("age"));//true

安全类 (无论是new还是函数直接调用都产生对象)*

    /* 
        无论是new还是函数直接调用都产生对象
            问题:当调用函数的时候产生和new操作一样的对象
                1、判断函数不是new的操作
                2、 return new 函数
    */
    function Student(name, sex) {
        if (!(this instanceof Student)) {
            return new Student(name, sex);
        }
        this.name = name;
        this.sex = sex;
    }
    var s1 = new Student('xiaoming', 'nan');  
    var s2 = Student('lili', 'nv');  
    console.log(s1, s2);

继承
类式继承:
问题 : 继承了原型对象中很多无用的属性和方法

    // Person
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            alert(this.name)
        }
    }
   function Student(name,age,sex,grade){
            this.name = name;
            this.age = age;
            this.sex= sex;
            this.grade = grade;
   }
    //类式继承 子类构造函数的原型指向父类的实例
    Student.prototype=new Person();
    //子类构造函数的原型的constructor指向子类 (完成了原型链的修改)
    Student.prototype.constructor=Student;
    //给子类添加方法必须在继承之后
    Student.prototype.say=function(){
        console.log(222)
    }
    var xiaoming=new Student("小明",18,"男",88)
    console.log(xiaoming);//子类构造函数的原型就指向了父类的实例

构造函数式继承(不是真的继承,只是简化了重复赋值的问题)

    //构造函数式的继承
    function Student(name,age,sex,grade){
        Person.apply(this,arguments)
        this.grade=grade;
    }
    Student.prototype.say=function(){
        console.log(222)
    }
    var xiaoming=new Student("小明",18,"男",88)
    xiaoming.sayHello();
    console.log(xiaoming);//只是简化了重复赋值的问题,子类构造函数的原型指向没有改变

组合继承(类式继承和构造函数继承的结合)
问题 : 继承了原型对象中很多无用的属性和方法

function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            alert(this.name)
        }
    }
    //组合继承  (类式继承和构造函数继承的结合)
    function Student(name,age,sex,grade){
        //构造函数继承(解决重复赋值的问题)
        Person.apply(this,arguments)
        this.grade = grade;
    }
    //类式继承 (继承原型上的方法)
    Student.prototype=new Person()
    Student.prototype.constructor=Student;
    Student.prototype.Hello=function(){
        console.log("hello");
    }
    var xiaoming=new Student("小明",18,"男",88)
    console.log(xiaoming);

寄生式继承:
在这里插入图片描述

	//构造函数
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            alert(this.name)
        }
    }
    function Student(name, sex, age, grade) {
           this.name = name;
           this.age = age;
           this.sex= sex;
           this.grade = grade;
     }
    Person.prototype.show=function(){
        console.log("show")
    }

    //寄生类继承
    function Fun(Parent,Son){
        //创建一个空的构造函数(寄生类)
        var F=function(){

        };
        //让寄生类的原型指向父类的原型
        F.prototype=Parent.prototype;
        //让子类的原型指向寄生类的实例
        Son.prototype=new F();
        //设置constructor
        Son.prototype.constructor=Son;
    }

    Fun(Person,Student);
    var xiaoming=new Student("小明",18,"男",88)
    console.log(xiaoming);
    xiaoming.show();//show

寄生组合式继承()

	//构造函数
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.sayHello=function(){
            alert(this.name)
        }
    }
    Person.prototype.show=function(){
        console.log("show")
    }
    function Student(name,age,sex,grade){
        //构造函数继承(解决重复赋值的问题)
        Person.apply(this,arguments)
        this.grade = grade;
    }
    
    //寄生类继承
    function Fun(Parent,Son){
        //创建一个空的构造函数(寄生类)
        var F=function(){

        };
        //让寄生类的原型指向父类的原型
        F.prototype=Parent.prototype;
        //让子类的原型指向寄生类的实例
        Son.prototype=new F();
        //设置constructor
        Son.prototype.constructor=Son;
    }

    Fun(Person,Student);
    var xiaoming=new Student("小明",18,"男",88)
    console.log(xiaoming);
    xiaoming.show();//show
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值