继承

//原型链继承
        function superType() {
            this.property = true;
        }
        superType.prototype.getSuperValue = function(){
            return this.property;
        };
        function SubType(){
            this.subproperty = false
        }
        //继承了subType
        SubType.prototype = new superType();
        SubType.prototype.getSubValue = function () {
            return this.subproperty
        };
        var instance = new SubType();
        alert(instance.getSuperValue()); //true
        //调用instance.getSuperValue()会经历三个步骤,1:搜索实例,2:搜索SubType.prototype;搜索superType.prototype==============
        //SubType继承了superType,而superType继承了Object。当调用了instance.toString()时,实际上市保存在Object.prototype中的那个方法

有两种方法确定原型和实例之间的关系

1:实例和原型中的出现过的构造函数都会返回true

        alert(instance instanceof Object)//true
        alert(instance instanceof SuperType)//true
        alert(instance instanceof SubType)//true    
第二种方式是使用 isPrototypeOf(),只要在原型链中出现过的原型。都会返回true;
        alert(Object.prototype.isPrototypeOf(instance))//true
        alert(SuperType.prototype.isPrototypeOf(instance))//true
        alert(SubType.prototype.isPrototypeOf(instance))//true

3:谨慎地定义方法

 //原型链继承
        function SuperType() {
            this.property = true;
        }
        SuperType.prototype.getSuperValue = function(){
            return this.property;
        };
        function SubType(){
            this.subproperty = false
        }
        //继承了subType
        SubType.prototype = new SuperType();
        //添加新方法
        SubType.prototype.getSubValue = function () {
            return this.subproperty
        };
        //重写超类型中的方法
        SubType.prototype.getSuperValue = function () {
            return false
        }
        var instance = new SubType();
        alert(instance.getSuperValue()); //false

使用对象字面量会导致错误,刚刚把SuperType的实例赋给了原型,紧接着又将原型替代成一个对象字面量导致原型链被切断,现在的原型包含一个Object实例,而非SuperType的实例,因此我们设想中的原型链已经被切断--SubType和SuperType之间已经没有关系了

 //原型链继承
        function SuperType() {
            this.property = true;
        }
        SuperType.prototype.getSuperValue = function(){
            return this.property;
        };
        function SubType(){
            this.subproperty = false
        }
        //继承了subType
        SubType.prototype = new SuperType();
        //使用对象字面量 会使上一行代码无效
        SubType.prototype = {
            getSubValue : function () {
                return this.subproperty
            };
        }
        var instance = new SubType();
        alert(instance.getSuperValue()); //false

原型链的问题

1:原型属性会被所有实例共享;

2:没有办法在不影响对象实例的情况下,给超类型的构造函数传递参数

        function SuperType() {
            this.colors = ["red","blue","green"];
        }
        function SubType(){
        }
        //继承了subType
        SubType.prototype = new SuperType();
        var instance1 = new SubType();
        instance1.colors.push("black");
        alert(instance1.colors)
        var instance2 = new SubType();
        alert(instance2.colors)//["red","blue","green","black"];

借用构造函数,函数复用无从谈起。

        function SuperType() {
            this.colors = ["red","blue","green"];
        }
        function SubType(){
             //继承了subType
             SuperType.call(this);
        }
        var instance1 = new SubType();
        instance1.colors.push("black");
        alert(instance1.colors)
        var instance2 = new SubType();
        alert(instance2.colors)//["red","blue","green"];

传递参数

        function SuperType(name) {
            this.name = name
        }
        function SubType(){
             //继承了superType,同时还传递了参数
             SuperType.call(this,"gay");
             //实例属性
             this.age = 29;
        }
        var instance = new SubType();
        alert(instance.name)//gay
        alert(instance.age)//29    

组合继承,有时候也称为伪经典继承,指的是将原型链和构造函数的技术组合到一块。。思路:使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承。使用最多的方法

        function SuperType(name) {
            this.name = name;
            this.colors = ["red","blue","green"];
        }
        SuperType.prototype.sayName = function () {
            alert(this.name)
        }
        function SubType(name,age){
             //继承属性
             SuperType.call(this,name);
             //实例属性
             this.age = 29;
        }
        //继承方法
        SubType.prototype = new SuperType();
        SubType.prototype.sayAge = function () {
            alert(this.age)
        }
        var instance1 = new SubType("gay",29);
        instance1.colors.push("black");
        alert(instance1.colors)//"red","blue","green","black"
        instance1.sayName();//"gay"
        instance1.sayAge();//29

        var instance2 = new SubType("blue",27);
        alert(instance2.colors)//"red","blue","green"
        instance2.sayName();//"blue"
        instance2.sayAge();//27

原型式继承

//ES5通过新增的Object.creat()方法规范化了原型式继承。这个方法接受两个参数,一个用作新对象原型的对象和(可选的)一个为新对象定义额外的对象。
        var person = {
            name:"gay";
            friend:["1","2","3"]
        };
        //第二个参数可有可无,和Object.defineProperties()方法的第二个参数格式相同
        var anotherPerson = Object.creat(person,{
            name:{
                value:"blue"
            }
        })
        //在没有必要兴师动众地创建构造函数,而只想让一个对象和另外一个对象保持类似的情况下,原型式继承是完全可以胜任的。

寄生组合式继承

        function inheritPrototype(subType,superType){
            var prototype = object(superType.prototype);
            prototype.constructor = subType;
            subType.prototype = prototype;
        };
        function superType(name) {
            this.name = name;
            this.colors = ["red","blue","green"];
        }
        superType.prototype.sayName = function () {
            alert(this.name)
        }
        function subType(name,age){
             //继承属性
             SuperType.call(this,name);
             //实例属性
             this.age = 29;
        }
        inheritPrototype(subType,superType);
        subType.prototype.sayAge = function () {
            alert(this.age)
        }
        //这个例子只调用了一次SuperType构造函数,并且因此避免了在SubType.prototype上面创建不必要的多余的属性。与此同时,原型链还能保持不变,因此,还能正常的使用instanceof和isPrototype()。寄生组合式继承是引用类型最理想的继承规范
原文地址:https://www.cnblogs.com/mr-pz/p/5920324.html