继承、原型链继承、拷贝继承

 0.为什么要使用继承

方法可能功能相似,但是不是同一个方法(没有指向同一块内存,会造成内存浪费)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function Person(name,age){
        this.name=name;
        this.age=age;
        this.say=function(){}
    }
    var p1=new Person();
    var p2=new Person();
    
    //p1对象和p2对象的say方法是否是同一个方法:false
    console.log(p1.say===p2.say);

    //由于say方法可能功能相似,但是不是同一个方法(没有指向同一块内存,会造成内存浪费)
    //解决方案:把say方法写在他们共同的(父对象)中
    //其实他们共同的父对象,就可以通过:Person.prototype来获取

    //-->只要把say方法写在Person.prototype中,那么say方法就是同一个方法
    Person.prototype.run=function(){
        console.log('时速500KM');
    }
    //此时p1和p2都可以访问到run方法
    p1.run();
    p2.run();
    //验证p1.run和p2.run是否是同一个方法?
    console.log(p1.run == p2.run); //指向同一个方法,这种方法避免了内存的浪费
    
    console.log(p1.run == Person.prototype.run);
    //true

    var p3=new Person();
    console.log(p3.run == p1.run); //true
    console.log(p3.run === p1.run);//true
    //结论:只要往某个构造函数的prototype对象中添加某个属性、方法,那么这样的属性、方法都可以被所有的构造函数的实例所共享
    //==>这里的【构造函数的prototype对象】称之为原型对象
    //  Person.prototype是 p1 p2 p3 的原型对象
    //  Person.prototype是Person构造函数的【实例】的原型对象

    //猜猜看?
    //  Person的原型对象是谁呢?
    //  -->首先要知道Person的构造函数:-->Function
    //  -->所以Person的原型对象是:Function.prototype

    //  p1的原型对象是谁呢?
    //  -->首先要知道p1是谁创建的?    -->Person
    //  -->所以p1的原型对象时:     Person.prototype

</script>
</html>

 0.1继承方法实现1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function Dog(){

    }
    var d1=new Dog();
    //为了让d1有一个叫的方法,
    //不行:d1.say=function(){}
    //正确:
    Dog.prototype.say=function(){
        console.log('汪汪汪');
    }
    
    //继承的第一种实现方式:原型链继承
</script>
</html>

 0.2继承方法实现2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function Cat(name){
        this.name=name;
    }
    var tom=new Cat("汤姆");
    //目的:把say方法放在tom的原型对象中(Cat.prototype)
    Cat.prototype.say=function(){}

    //问题:
    Cat.prototype.s1=function(){}
    Cat.prototype.s2=function(){}
    Cat.prototype.s3=function(){}
    Cat.prototype.s4=function(){}
    Cat.prototype.s5=function(){}
    //通过上面的方式,给tom的原型对象添加了好多方法,也就是让tom拥有了好多方法,但是代码产生了不少的冗余(重复)

    //-->为了减少这种重复,改良版:
    Cat.prototype = {
        a1:function(){},
        a2:function(){},
        a3:function(){},
        a4:function(){},
        a5:function(){}
    }
    console.log(tom.s1);    //可以访问
    console.log(tom.a1);    //undefined
    //原因:tom对象在创建的时候已经有了一个确定的原型对象,就是旧的Cat.prototype
    //由于Cat.prototype后面被重新赋值,但是tom对象的原型对象却没有改变,所以tom对象并不能访问到新原型对象中的a1-a5方法

    //如何解决这个问题?
    //-->先改变原型、再创建对象






    
    //继承的第一种实现方式:原型链继承
</script>
</html>

1.原型链继承 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function Tiger(){

    }
    Tiger.prototype={
        a:function(){
            
        },
        b:function(){

        }
    }
    //创建tiger实例,此时的tiger实例的原型对象是新原型,所以tiger可以访问到新原型中的属性和方法(a/b)
    var tiger=new Tiger();
    console.log(tiger.a);
    console.log(tiger.b);


</script>
</html>

2.拷贝继承

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    //1、已经拥有了o3对象
    var o3={gender:"男",grade:"大四",group:"第五组",name:"itwangyangcoder"};
    //2、创建一个o3对象的拷贝(克隆):for...in循环
    var o4={};
        //a、取出o3对象中的每一个属性
    for (var key in o3) {
                //key就是o3对象中的每一个属性
        //b、获取到对应的属性值
        var value = o3[key];
        //c、把属性值放到o4中
        o4[key] = value;
    }

    //3、修改克隆对象,把该对象的name属性改为"李四"
    o4.name="coder"
    console.log(o4);    //最终的目标对象的结果

    //。。。后续如果修改了o4对象中的相关属性,就不会影响到o3

</script>
</html>

3.封装拷贝继承函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function extend(source,target){
        for (var key in source) {
                //key就是o3对象中的每一个属性
            //b、获取到对应的属性值
            var value = source[key];
            //c、把属性值放到o4中
            target[key] = value;
        }
    }

    var o3={gender:"男",grade:"初三",group:"第五组",name:"itwangyangcoder"};

    var o4={};
    extend(o3,o4);
    o4.name="coder";

    var o5={};
    extend(o3,o5);
    o5.name="李小龙";


</script>
</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值