• JS中写继承的方式


    有父子两个函数,代表两个类:

    var parent = function(){}
    var child = function(){}

    一、直接继承

    child.prototype = new parent();
    child.prototype.constructor = child;

    这种方式有风险,说是如果parent中有this,然后parent在其他地方给this混入了其他东西,child的继承原型中就会莫名多了其他不属于他们的东西,这样不好。。。

    -----------------

    2020.04.24,来针对上面这种继承方式的风险进行说明。

    假设parent的构造函数中包含了很多属性,其中包括引用类型的,也就是这样的:

    function Parent(name,age){
        this.name=name
        this.age=age
        this.arr=[]
        this.obj={}
    }
    

      其中arr和obj就是风险,如果设置child.prototype=new Parent(name,age),child.prototype.constructor=child,那么接下来child的所有实例化对象都会包含这两个arr,obj,并且引用地址都是同一个,那么问题就来了,假设有两个Child的实例化对象,var child1=new Child(),var child2=new Child(),如果child1.arr.push(xxxx),或者child1.obj.xxx=xxxx,那么完蛋了,child2拿到的arr和obj都会受到影响,拿到的都是受到影响之后的对象。

    化解这种风险的方法:也可以在Child的构造函数中,写自己的特有的属性之前调用一下Parent.call(this),这样就可以将父类的属性变成自己的属性了,而不再是共享在原型中的了,这样操作以后,哪怕再写Child.prototype=new Parent()也不怕了,因为继承关系,子类属性已经在了,哪怕原型中有同名属性也不怕。那么就怕使用delete之后再改原型对应的属性,那么还是有风险【捂脸】。

    而下面的借助中间空函数的做法,就能完全避免这种问题,因为空函数本身不引入任何this的东西。

    -----------------

    二、借助中间空函数

    var nop = function(){}
    nop.prototype = parent.prototype;
    child.prototype = new nop();
    child.prototype.constructor = child;

    空函数的办法,就解决了第一种方法的隐患,空函数中没有任何this相关的隐患,如果封装在一个继承函数里,函数外面根本拿不到里面的这个空函数,安全可靠。

    三、Object.setPrototypeOf

    Object.setPrototypeOf(child.prototype,parent.prototype);

    该方法是ES6新增的设置原型的方法,它可以直接关联两个对象,而不需要重新将child的constructor手动拉回,简单方便,实在是原型继承,必备良药。

    四、Object.create

    child.prototype = Object.create(parent.prototype);
    child.prototype.constructor = child;

     此种方法也是安全可靠,使用方便无隐患,缺点也是需要手动设置一下自己的constructor.

  • 相关阅读:
    [mysql练习]多行结果合并问题练习
    【Python】Python多进程练习
    【mysql练习】转置,总计,分组
    【Mysql】HDFS文件上传流程
    [Jmeter][基础]Jmeter连接IMPALA
    【Linux】 -bash-4.2#问题和Cannot allocate memory
    微服务学习之路
    好的东西一定要收藏-持续更新
    Python日期的加减等操作
    NGINX动态增加模块,平滑升级
  • 原文地址:https://www.cnblogs.com/liujiekun/p/11532807.html
Copyright © 2020-2023  润新知