zoukankan      html  css  js  c++  java
  • 【JavaScript回顾】继承

    组合继承

      组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的 技术组合到一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型属性和方 法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数 复用,又能够保证每个实例都有它自己的属性。下面来看一个例子:

      

       <script>
            function Person(name, age, friends) {
                this.name = name;
                this.age = age;
                this.friends = ["Carol", "Seylia"];
                if (typeof this.ShowPerson != "function") {
                    this.ShowPerson = function () {
                        var message = "name:" + this.name + "
    
    age:" + this.age + "
    friends:";
                        this.friends.forEach(function (value, index, arr) {
                            message += " " + value;
                        });
                        alert(message);
                    }
                }
            }
    
            function Student(name, age, job) {
                Person.call(this, name, age);
                this.job = job;
            }
    
            //这里继承了
            Student.prototype = new Person();
            Student.prototype.constructor = Student;
    
            var s1 = new Student("gck", 26, "Sf");
            s1.friends.push("Core");
            s1.ShowPerson();
    
            var s2 = new Student("Carol", 28, "Sf");
            s2.ShowPerson();
        </script>

    组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为 JavaScript中常用的继 承模式。而且,instanceof 和 isPrototypeOf()也能够用于识别基于组合继承创建的对象.

      注:不准备说原型链和借用构造,因为这两个缺陷太大,不过有想了解的可以查一下。

    寄生组合式继承

    面说过,组合继承是 JavaScript 常用的继承模式;不过,它也有自己的不足。组合继承大的 问题就是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是 在子类型构造函数内部。没错,子类型终会包含超类型对象的全部实例属性,但我们不得不在调用子 类型构造函数时重写这些属性,所以我用寄生组合继承:

      所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背 后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型 原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型 的原型。寄生组合式继承的基本模式如下所示。

    <script>
            //如果Object.create浏览器不支持,则用这个方法代替
            function object(o) {
                function F() { }
                F.prototype = o;
                return new F();
            }
    
            function inheritPrototype(subType, superType) {
    
                //创建对象    
                var prototype = Object.create(superType.prototype);//这个方法IE9+才支持
                //var prototype = object(superType.prototype);
    
                //增强对象   
                prototype.constructor = subType;
                 
                //指定对象 
                subType.prototype = prototype;
               
            }
            
    
            function Person(name, age, friends) {
                this.name = name;
                this.age = age;
                this.friends = ["Carol", "Seylia"];
                if (typeof this.ShowPerson != "function") {
                    this.ShowPerson = function () {
                        var message = "name:" + this.name + "
    
    age:" + this.age + "
    friends:";
                        this.friends.forEach(function (value, index, arr) {
                            message += " " + value;
                        });
                        alert(message);
                    }
                }
            }
    
            function Student(name, age, job) {
                Person.call(this, name, age);
                this.job = job;
            }
    
            //这里继承了
            inheritPrototype(Student, Person);
    
            var s1 = new Student("gck", 26, "Sf");
            s1.friends.push("Core");
            s1.ShowPerson();
    
            var s2 = new Student("Carol", 28, "Sf");
            s2.ShowPerson();
    
        </script>

    这个例子的高效率体现在它只调用了一次Person构造函数,并且因此避免了在 Student. prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf()。开发人员普遍认为寄生组合式继承是引用类型理想的继承范式。
    YUI

  • 相关阅读:
    C#-项目属性设置
    SQL--连接字符串总结
    希尔排序实现(不太满意)
    选择排序实现
    用位运算实现 | 与 ^ 的功能
    如何初始化一个定长List<T>
    线程池与Threadlocal
    常用类
    基本数据类型介绍
    eclipse快捷键
  • 原文地址:https://www.cnblogs.com/guochenkai/p/4011233.html
Copyright © 2011-2022 走看看