zoukankan      html  css  js  c++  java
  • javaScript实现继承

     

        <script type="text/javascript">
    
                function People(name){
    
                        this.name = name;
    
                        this.job = "程序员";
    
                }
    
                //这里是和构造函数模式继承的区别所在,因为把方法定义在了原型对象上。所以可解决函数复用的问题。把可复用的定义在原型对象上,所有实例都可以共享
    
                //把引用类型的数据定义在构造函数中,就不会共享(每次创建都会分配新的内存空间)
    
                People.prototype.sayname = function(){
    
                    console.log(this.name);
    
                }
    
                function Person(name,age){
    
                    //person继承people方法的属性
    
                    People.call(this,name);
    
                    this.age = age;
    
                }
    
                //每次new一个新的上下文,导致引用类型的数据不会共享
    
                Person.prototype = new People();
    
                Person.prototype.constructor = Person;
    
                Person.prototype.sayage = function(){
    
                    console.log(this.age);
    
                }
    
                var stu = new Person("prj",21);
    
                stu.job = "ceo";
    
                console.log(stu.job);
    
                stu.sayname();
    
                stu.sayage();    
    
                var stu1 = new Person("wxj",20);
    
                console.log(stu1.job);
    
                stu1.sayname();
    
                stu1.sayage();
    
            </script>

      这种方法的名称叫做:组合继承方式。所谓组合是,原型继承和构造函数继承方法的组合。

      单独使用这两种中的任何一个都会有比较明显的问题:原型链继承,会导致超类构造函数中的引用类型数据共享。构造函数模式继承:这种方式,使得函数的可复用性完全丧失,如果一个函数可以重复使用的话,每次都会为这个函数分配空间,如果这样的函数很多的话,就会造成内存空间的浪费。

      组合继承方式集合了他们的优点:原型链方式的函数可复用和构造函数模式的内容封闭,引用类型不会共享。

      唯一有点遗憾的地方是:组合继承最大的 问题就是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是 在子类型构造函数内部。这样的后果是:第一次调用时,会使name属性和job属性出现在实例上,第二次调用会使name属性和job属性出现在原型上。就像这样:

    虽然这并不影响我们想要的所有功能,但是精益求精的coder,还是想出了解决办法,就是我们要说的第二种方式:

      寄生组合式继承:

      这种继承方式解决了上面那种方式带来的缺点:上面的缺点在于,让实例出现在了不该出现的地方,归根接底,是在new 构造函数的时候出的问题,因为job属性和name属性,已经出现在了该出现的位置,我们这次只想继承超类的原型。ok,那么我们需要将超类的prototype拷贝一份,送给子类就可以了。

      

         <script type="text/javascript">
                function People(name){
                        this.name = name;
                        this.job = "程序员";
                }
                //这里是和构造函数模式继承的区别所在,因为把方法定义在了原型对象上。所以可解决函数复用的问题。把可复用的定义在原型对象上,所有实例都可以共享
                //把引用类型的数据定义在构造函数中,就不会共享
                People.prototype.sayname = function(){
                    console.log(this.name);
                }
                function Person(name,age){
                    //person继承people方法的属性
                    People.call(this,name);
                    this.age = age;
                }
                //每次new一个新的上下文,导致引用类型的数据不会共享
    //            Person.prototype = new People();
    //            Person.prototype.constructor = Person;
    
                (function(sub,sup){
                    var prototype = sup.prototype;
                    prototype.constructor = sub;
                    sub.prototype = prototype;
                })(Person,People)
                Person.prototype.sayage = function(){
                    console.log(this.age);
                }
                
                var stu = new Person("prj",21);
                stu.job = "ceo";
                console.log(stu.job);
                stu.sayname();
                stu.sayage();
                console.log(stu);
                
                var stu1 = new Person("wxj",20);
                console.log(stu1.job);
                stu1.sayname();
                stu1.sayage();
            </script>

    唯一改变的地方在于红色代码部分:使用寄生的方式,将父类的prototype赋值给了子类的prototype;

     

    可以发现子类的原型中,没有了name和job属性

    原创学习博客,欢迎交流,转载说明噢~~~

  • 相关阅读:
    Spring Could not find unique TaskExecutor bean 错误
    Postman 测试 API 如何上传文件
    Spring Boot 项目上传日志到 Azure Application Insights
    Spring Boot 和 Hibernate 的 H2 数据库配置来进行启动测试
    android TextView多行数据显示
    MarkDown 查看器 typora
    Ubuntu16.04多个版本python编译器的安装和切换
    关于LPC824Lite开发板下载程序时提示"Invalid ROM Table"
    8寸防震三防平板电脑Windows/安卓
    HaaS100 OLED信息屏显示案例
  • 原文地址:https://www.cnblogs.com/pianruijie/p/8006460.html
Copyright © 2011-2022 走看看