JS高级继承方法

前言:

    上篇文章说了下,原型链继承    临时构造器继承!
    下面我们来说说继承其它的方法例如:属性拷贝,对象之间继承……等。
一、属性拷贝

    属性拷贝也是继承的一种方式。属性拷贝是子对象会继承父对象原型链上所有的自身属性。但是,属性拷贝有一个问题,该方法只针对于对于基本数据类型有效,JS中对象的传递大多数是引用传递,仅仅是传递对象的地址,子对象修改, 父对象中也相应的会改变。
如下图:

属性拷贝2.png

属性拷贝代码:

function extend2(Child,Parent){
            var c = Child.prototype;
            var p = Parent.prototype;
            // 循环遍历 Parent中的属性,复制给Child
            for(var i in p){
                c[i] = p[i];
            }
            // uber  实现子级属性能找到父级的属性
            Child.uber = Parent.prototype;
        }

例:

function Person(){}
        Person.prototype.age = 0;
        Person.prototype.description = "人类";
        Person.prototype.hoby = ["权利","金钱"];
        Person.prototype.say = function(){
            return "我的年龄" + this.age;
        };
function Student(){}
        // 实现继承关系
        extend2(Student,Person);
        Student.prototype.description = "学生";
       // 实例化一个学生对象
        var stu = new Student();
        stu.hoby.pop();
        console.log(stu.description);
        console.log(stu.hoby);

        var stu1 = new Person();    
        console.log(stu1.description);
        console.log(stu1.hoby);

就代码而言,需要更改constructor属性吗? 答案:当然不用 。
通过extend2(Student,Person);代码,所以Student中没有的属性都可以从Person中拷贝过来,因此这就是属性拷贝。但是有一个问题就是如果你修改Student中的方法、对象、数组。那就会把Person中的也改掉,所以这种方法也属于浅拷贝。这个问题一会会在深拷贝中解决。

二.对象之间的继承

到目前来说,我们都是通过构造函数实现的继承关系,其实,我们完全可以不使用构造函数就可以实现继承关系直接使用对象完成继承关系的建立。

对象代码:
function extend3(parent,child){
         // 如果实参第二个参数传递了,那么child就是实参的值
         // 如果实参第二个参数没有传递,那么child就是个空对象
            child = child || {};
            for(var i in paren  ){
                child[i] = parent[i];
            }
            child.uber = parent;
            return child;
        }

例:

var per = {
            description:"人类",
            age:0,
            hoby:["权利","金钱"],
            say:function(){
                return this.age;
            }   
        };

function Student(){}
var stu = new Student();
//建立继承关系(让一个已知的对象继承自per对象)
        extend3(per,stu);
        stu.description = "学生";
        console.log(stu.age);

        stu.hoby.pop();      
        console.log(stu.hoby);
        console.log(per.hoby);

        // 子对象访问父对象中的description属性
        console.log(stu.uber.description);

        // 创建一个继承per对象的对象
        var t = extend3(per);
        console.log(t.description);

对象继承也属于浅拷贝。对象继承也会有一个与属性拷贝类似的bug,也会用深拷贝来解决!!!

深拷贝:内存拷贝,将内存完整的拷贝一份
浅拷贝:引用拷贝,只复制对象地址
说了这么多方法,深拷贝终于来了!!!!

三、深拷贝

        function  deepCopy(parent,child){
            child = child || {};
            // 遍历父对象属性
            for(var i in parent){
                // 判断是否是自身属性
                if(parent.hasOwnProperty(i)){
                     if(/*是对象类型*/typeof parent[i] === "object"){
                        // 判断是属性是否是数组([])还是对象({})
                        child[i] = Array.isArray(parent[i])?[]:{};
                        //把parent[i]里的属性赋值给child[i]里面去
                        deepCopy(parent[i],child[i]);
                    }else{
                        // 基本数据类型
                        child[i] = parent[i];
                    }
                }
            }
            return child;
        }
        var per = {
            description:"人类",
            age:0,
            hoby:["权利","金钱"],
            say:function(){
                return this.age;
            }   
        };
        // 对象t继承自对象per
        var t = deepCopy(per);
        t.hoby.pop();
        console.log(t.hoby);
        console.log(per.hoby);
        console.log(t.description);

用深拷贝就可以看出如果修改方法、数组、对象就不会对父对象产生变化。
四、原型继承与属性拷贝的混合应用

写段代码来表示,如下:

var per = {
            description:"人类",
            age:0,
            hoby:["权利","金钱"],
            say:function(){
                return this.age;
            },  
        };

        var base = {
            name:"zhang",
            height:180,
            weight:70,
        };

        function extend(p1,p2){
            var child;
            var F = function(){};
            F.prototype = p1;
            child = new F();

            for(var i in p2){
                child[i] = p2[i];
            }
            return child;
        }
        var t = extend(per,base);
        console.log(t)

五、多重继承

        var per1 = {
            name:"zhang",
        }
        var per3 = {
            age:"16",
        }
        var per5 = {
            name:"kun",
            height:"180",
        }
        var per6 = {
            weight:"70",
        }
        
        function muli(){
            var child = {};
                for(var i = 0 ;i <arguments.length ;i++){
                    arguments[i];
                    for(var j in arguments[i]){
                        child[j] = arguments[i][j];
                    }
                }
            return child;
        }
        // 对象t继承子对象per1,per3,per5,per6
        // 注意:如果父对象中存在相同的属性,参数后面对象中的属性
        //      会覆盖掉前面参数对象中的属性
        var t = muli(per1,per3,per5,per6);
        console.log(t);

JS高级理清楚面向对象、继承、闭包还是挺重要的。
继承的方法就先写到这里!!!后面会陆续更新!!!Loading...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • js中的继承: Object是所有对象的父级/父类型/超类型,js中所有的对象都直接或间接的继承自Object. ...
    doudouY075阅读 480评论 0 2
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 1,454评论 3 12
  • 1,javascript 基础知识 Array对象 Array对象属性 Arrray对象方法 Date对象 Dat...
    Yuann阅读 950评论 0 1
  • 你为什么写诗呢 受什么刺激吗 看破红尘了 有点傻吧 写诗能赚钱吗 不知为什么 当今的人们 见了一个写诗的人 居然会...
    徐一村阅读 359评论 3 4
  • 他们说,深爱,请陌生…… 年轻的心总是看得远的,也不容易满足,当有一天,我们因为珍惜而靠近对方,便渐渐明白昔日,过...
    麦迪大猩猩阅读 267评论 0 0