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属性

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

  • 相关阅读:
    SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法
    备份还原工具—ghost
    太多的if,太多的痛苦
    C#中使用GUID
    WinForm开发中,将Excel文件导入到DataGridView中时,获取Excel中所有表格的名称。
    使用ASP调用C#写的COM+组件
    COM+ and the .NET Framework 虽是英文但比较全面
    在C#中使用COM+实现事务控制
    COM+ and the .NET Framework
    管理员ID过期,无人能够管理Domino服务器
  • 原文地址:https://www.cnblogs.com/pianruijie/p/8006460.html
Copyright © 2011-2022 走看看