美文网首页
JS面向对象(继承)

JS面向对象(继承)

作者: 红鲤鱼不理绿鲤鱼 | 来源:发表于2017-05-10 10:42 被阅读0次

    1.什么继承?

    继承就是某个对象可以访问另一个对象的属性和方法,我们认为他们之间存在继承关系。

    举例:

    
    function Chinese(){}
    
    var jack=new Chinese();
    
    //jack可以访问到自身的属性,还可以访问到Chinese.prototype对象中的属性和方法,
    
    //--->我们说jack继承自Chinese.prototype
    
    //--->jack.__proto__===Chinese.prototype
    
    

    2.继承主流的实现方式:

    1.原型式继承

    a.扩展原型对象

     function Person(){}
        //一个函数创建好之后,就会又一个默认的原型对象,需要给这个对象添加属性、方法,我们把这样的方式称之为扩展原型对象实现继承
        Person.prototype.run=function(){
            console.log("run");
        };
        var p1=new Person();
        console.log(p1.constructor);//Person
        //p1
        //p1.__proto__--->Person.prototype
        console.log(p1.run);
        //有时候我们需要给原型对象中扩展多个属性和方法,如果使用扩展原型对象来实现,出现一些重复的代码,我们思考能不能把这些重复封装起来,解决方案:替换原型对象实现继承
        Person.prototype.run1=function(){
            console.log("run");
        };
        Person.prototype.run2=function(){
            console.log("run");
        };
        Person.prototype.run3=function(){
            console.log("run");
        };
        Person.prototype.run4=function(){
            console.log("run");
        };
        Person.prototype.run5=function(){
            console.log("run");
        };
    

    b.替换原型对象

        function Person(){}
        //一个函数创建好之后,就会又一个默认的原型对象,需要给这个对象添加属性、方法,我们把这样的方式称之为扩展原型对象实现继承
    
        //替换原型对象
        Person.prototype={
            constructor:Person,
            r1:function(){},
            r2:function(){},
            r3:function(){}
        };
    
        var p1=new Person();
        console.log(p1.r1);//p1.__prpto__:Person.prototype
    

    2.混入继承(拷贝继承)

    function foo(name,age,gender,height,width,language,color){}
    
        foo("zhangsan",20,"男",180,180,"中文","黄色");
    
        function foo2(obj){
            this.name=obj.name;
            this.age=obj.age;
            this.gender=obj.gender;
            this.height=obj.height;
            this.language=obj.language;
            this.width=obj.width;
            this.color=obj.color;
    
            //上面的代码又产生了很多的重复的字符,就希望有某种方式可以减少重复
            //解决方案:混入继承:for...in循环
            for (var key in obj) {//key保存了obj中每一个属性的名称:字符串的值
                //获取指定属性的值:
                this[key]=obj[key];//举例:this["name"]=obj["name"]
            }
        }
        foo2({
            name:"zhagnsan",age:18,
            gender:"男",height:180,width:200,language:"英语",
            color:"白色"
        });
    
    
        /**
         * 将某个对象中的属性分别拷贝到另一个对象中
         * 把提供数据的对象称之为数据源对象(source object)
         * 把接收数据的对象称之为目标对象(target object)
         */
        function mixin(target,source){
            for (var key in source) {
                //将source中的指定的属性拷贝到target中-->给target添加同名属性
                target[key]=source[key];
            }
    
            //告诉用户拷贝的结果:
            return target;
        }
    
        var o1={name:"zhagnsan",age:25,gender:"男"};
        var o2={};
        console.log(mixin(o2,o1));
    
        var o3={name:"zhagnsan",age:25,gender:"男"};
        var o4={length:10,gender:"女"};
        console.log(mixin(o4,o3));//o4-->{name:"zhangsan",age:25,gender:"男",length:10}
    
    

    3.原型式继承(经典继承)

     //原型式继承:经典继承-->由道格拉斯在蝴蝶书(javascript语言精粹)中提出
    
        function mixin(target,source){
            for (var key in source) {
                //将source中的指定的属性拷贝到target中-->给target添加同名属性
                target[key]=source[key];
            }
    
            //告诉用户拷贝的结果:
            return target;
        }
        var o3={name:"zhagnsan",age:25,gender:"男"};
        var o4={length:10,gender:"女"};
    
        //希望o4中可以访问到length/gender:"女"/-->name/age
        //实现思路:让o3和o4之间产生某个联系(继承关系)
        //      -->o4继承自o3
        //      -->o4.__proto__==o3     -->o4就不仅可以访问到自己的属性,也可以正常访问到o3的一些属性
    
        //不能直接使用:o4.__proto__==o3,因为__proto__属性是非标准属性,具有浏览器兼容性问题
        //曲线救国的方式:
        //想到之前:function Person(){}   var p1=new Person();  p1.__proto__===Person.prototype
    
        //为了实现上面的关系,需要进行相关的转换,也就是通过某个构造函数创建一个实例o4,执行构造函数的原型指向o3
        function F(){}
        F.prototype=o3;//让F的实例都可以访问到o3中的属性
        var o5=new F();//o5.__proto__===o3
        o5.length=10;
        o5.gender="女";
    
        console.log(o5.length);//自己的length
        console.log(o5.gender);//自己的gender
        console.log(o5.name);//自己没有,访问o3的name属性
    
        //总结:
        //原型式继承的功能:创建一个新的对象,让新的对象可以继承自指定的对象,从而这个新的对象既可以访问到自己的属性,也可以访问到指定的对象的属性
    
        //现代浏览器中:Object.create()实现了原型式继承(经典继承)
        //ES5(js语言规范的第五个版本)——Object.create()--->IE9以下不支持
        //var o6=Object.create(o3);//o6继承自o3
    
    
    
        //如果希望写出一段代码,实现原型式继承,让它可以兼容所有的浏览器
    
        //执行过程:首先判断浏览器是否存在这个方法,如果不存在,这个浏览器自己没有实现经典继承,就帮他实现
        //                              如果已经存在,就不需要进行任何操作
        //经过上面的处理之后,就实现了可以在任意浏览器版本中,可以调用Object.create()
        if(!Object.create){
            Object.create=function(parent){
                function F(){}
                F.prototype=parent;
                return new F();
            };
        }
        alert(Object.create.toString());
    
        var o7=Object.create(o3);//o6继承自o3
        alert(o7.name);
    
    
    

    4.借用构造函数继承

    5.寄生继承、寄生组合、组合继承

    相关文章

      网友评论

          本文标题:JS面向对象(继承)

          本文链接:https://www.haomeiwen.com/subject/ftiwtxtx.html