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

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

  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/pianruijie/p/8006460.html
Copyright © 2011-2022 走看看