搜索

首页  >  问答  >  正文

javascript继承问题

代码如下:

        function Father(){
            this.name = true;
            this.array = [];
        }
        Father.prototype.getFatherValue = function(){
            return this.property;
        }
        function Son(){
            this.sonProperty = false;
        }
        //继承 Father
        Son.prototype = new Father();
        var son1 = new Son();
        var son2 = new Son();

其中Father的array属性会被son1和son2共用,但是name属性不会被共用,我的理解是,son1和son2都会去Son.prototype找name属性,name属性应该也是被共用的呀,为什么不是呢?

迷茫迷茫2786 天前766

全部回复(3)我来回复

  • 为情所困

    为情所困2017-07-05 10:49:40

    因为数组是引用类型,对于father(new Father()),son1,son2,这三个实例来说,他们array保存的都是[]这个数组的引用,所以只要其中一个修改了,顺着引用找到内存中的数组就会修改,修改的就是同一个数组。而name = true,这个name是基本类型,在分别new实例的时候,会在内存中各开辟一块区域内存放它的值,因此上述三个实例的name对应的是不同内存区域的值,所以修改了就不会互相影响。
    看来楼上的一些回答后,思考了一下,发现我的理解,我的答案是有错的。保留原答案,下面更正一下。
    关于数组那一块没有问题,问题在name这个属性,对于son1,son2来说,他们是没有name这个属性的,所以在new的时候,应该是没有为他们的name开辟内存空间的。只有father这个实例有。
    son1,son2name值是通过原型链查找找到的,如果对son1.name进行赋值,那么相当于给son1这个实例添加了name属性,当然再次打印son1.name时取到的值是属于son1的name值,而打印son2.name,则会去原型链上找name,这个时候找到的是Fathername值,因此两个值不同,可能会给你造成没有共用的错觉。
    值得注意的是,如果son1.array[0] = 1这么赋值的话,那么对三个实例的array都会有影响,如果是son1.array = [1],这么赋值就不会,因为这时候array保留的是对[1]这个新数组内存地址的引用。

    回复
    0
  • 欧阳克

    欧阳克2017-07-05 10:49:40

    son1.array.push(1)
    son1.array // [1]
    son2.array // [2]
    
    son1.array = [2]
    son1.array // [2]
    son2.array // [1]

    你说array是共用的?

    回复
    0
  • 高洛峰

    高洛峰2017-07-05 10:49:40

    为什么说 name 属性不会被共用呢?

    原型链继承,就是顺着原型链一直找,直到找到后返回此值,如果找不到,返回 undefined

    如果我们给 Son 赋值

    son1.name = 'aa';
    son2.name = 'bbb';
    

    此时就是取实例的值。只有在 Son 没有相应的属性时,才去原型链找。

    回复
    0
  • 取消回复