基本是对的。SuperType.call(this,name);这句话,会出一个问题,就是,使得SuperType的内部的属性,就是那name和age属性,出现在SubType的内部,这里其实就是把SuperType执行了一遍。执行完之后
function SubType (name ,age){
    this.name = name;
    this.colors = ["red","blue","green"];
    this.age = age;
}这个函数就变成这个样子了,当然后面再次使用继承,在原型链上,依然会有name和colors属性,只是内部属性有更高的优先级,所以会把原型链上的覆盖掉。你可以确认一下,name属性,和color是属性,是不是在内部,
就是用那个,hasOwnProperty就行。
console.log(instance1.hasOwnProperty("name"));
这个方法,就可以判断,是不是在实例内部有这个属性,如果返回true,就代表实例内部存在,如果返回false则代表实例内部不存在,这个时候,要么就是存在于原型链上,要么就是不存在这个属性。你图中,继承是对着呢,就是两个构造函数的内部属性,没有画出,我就这么说一下。

解决方案 »

  1.   


    嗯。其实对这个call不是很理解,那请问下
    其实
    function Subtype(name ,age){
    this.age = age;
    SuperType.call(this,name);
    }//上面的这个函数是不是可以用下面的来理解呢?两者在执行后是不是效果也一样的?
    function SubType (name ,age){
        this.name = name;
        this.colors = ["red","blue","green"];
        this.age = age;
    }
    还有一个问题就是你上面提到的我在构造函数里没写那几个属性,是不是指的比如SuperType中应有的有name 和color属性?我刚看了下这个函数貌似没有,不晓得我看的方式有没有错,或者是我理解的有问题。我的理解是在构造函数里的属性在他实例化的时候,会在实例中体现==
    谢谢你的解答
      

  2.   

    图画的是对的~~~(1)首先说“上面的这个函数是不是可以用下面的来理解呢?两者在执行后是不是效果也一样的?”,回答是肯定的:效果一样。SubType里“SuperType.call...”的时候,SuperType只是一个普通函数被调用而已 作用就是给SubType的对象添加属性。(2)构造函数里this指定的属性是属于实例化后的对象的,构造函数只是一个函数 它不拥有这些属性。你的理解是对的。此外,1楼提到的也是需要注意的。即:
    instance1它自己有name和color属性,而它的原型(也就是superType的实例化对象)也具有name和color属性。因此,实际上instance1是具有两个name属性和两个color属性的。但是,在读取对象属性的时候,对象会现先检查自己有没有这个属性,如果有则停止搜索并读取;如果没有,才会继续向上到原型里找。所以尽管instance1里有重复的属性,但是instance1自身的属性优先级最高。
      

  3.   

    function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","green"];
    console.log(this === window);
    }
    SuperType("zhang");
    console.log(name);
            console.log(window.name);
    这里,为啥会这样呢?如果是直接运行这个函数,就会有this===window,这个时候,虽然也算是运行了下这个函数,但其根本就是:定义了几个全局变量而已。这一点就先到这里。至于call和apply这两个API,他们的作用就是去改变这个作用域,最明显的表示就是,改变构造函数中的this的指向。
    function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","green"];
    console.log(this === o);//这里也改动了一下;
    }
    var o = {};//我这里定义了一个空的对象。
    SuperType.call(o,"zhang");
    console.log(o.name);
    console.log(name);//这个地方就不会再存在了
    看看这个例子,首先第一点,this===o,这个应该很明白了吧,因为使用call方法,改变了this的指向。
    它本质上,就是把SuperType的内部的属性,添加到了o对象上面,你可以查看一下o对象包含的属性就能看到了。
    所以,这里o.name就是刚才输入的name,"zhang",可是接下来,直接打印name属性,也是显示“zhang”,这就是因为,刚才第一个例子的原因了,第一个例子中,this是指向window的,window下有一个自带的属性就是name,所以经过第一个例子,window.name已经被改变,所以这里name的值,还是“zhang”,当然如果你执行第二个例子之前,没有使用第一个例子,这个地方,就会显示window.name原本的值。也可以通过关闭浏览器重新打开,清除第一次改变的name。所以,一般情况下,不要使用name这个作为变量,万一和window.name的使用起了冲突,很难找问题的。如果不想关浏览器在测试,就把上面的name改成查看colors属性吧,直接查colors,会因为不存在而直接抛出错误的。这里只说了call的基本使用,具体怎么使用,以及和apply的区别,你自己去看些资料吧。实例化,实例化的实质,只是为了改变this的值。就像上面说的,就是改变this,实例化就是把this改变成实例化的那个变量了。
    var that;
    function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","green"];
    console.log(this === o);//这里也改动了一下;
    //为什么这里,在实例化的时候,会返回false?因为这个时候,实例化还么有结束,而在实例化完成之前,o还是没有赋值的哦,所有这里就不能这样来判断this的执行了。还是按照后面的使用,就可以判断出来了。
    that = this;
    //为了能暂时保持这个this的代表的值,就用这个全局变量暂时保存吧。
    }
    SuperType.prototype.sayName = function(){
    alert(this.name);
    };
    var o = new SuperType("zhang");
    console.log(that === o); //这里,就能证明,之前实例化时,其中的this,是被实例化为o了。
    console.log(o.name);
    console.log(colors);//这个地方就不会再存在了这里的一些东西,我在例子中简单的说了一下。至于你上面给的那段代码,我也就在代码中说说了:
    function Subtype(name ,age){
    this.age = age;
    SuperType.call(this,name);
    //这里这样写,要注意前后的顺序,使用call继承其他函数的内部属性,必须要写在最前面,因为如果你写在后面,如果SuperType中,有age这个属性,那么你这里新写的age属性,就会被SuperType中的属性覆盖。
    }
     
    //上面的这个函数是不是可以用下面的来理解呢?两者在执行后是不是效果也一样的?
    function SubType (name ,age){
        this.name = name;
        this.colors = ["red","blue","green"];
        this.age = age;
    //这样写,也没有错,之所以写成上面的那种形式,只是为了有更好的可重复利用性。打个比方,我在下面在定义一个SubType2.
    }
    //新定义的SubType2的所有属性是下面这些,和SubType只有一个属性是不同的,这里要怎么写,才能更好的利用已有的资源,并且在以后万一有改动时,可以更方便的维护呢?
    function SubType2 (name ,sex){
        this.sex = sex;
        this.colors = ["red","blue","green"];
        this.age = age;
    }//那就按照这样的写法,是不是更好?
    function SubType2 (name ,sex){
    SuperType.call(this,name);
        this.sex = sex;
    }//这里包含的属性比较少,所以看不出来好处,可是如果你每一个构造函数,都有十几个几十个,是不是有点能想象了?//这个主要是因为一些设计模式方面的东西了,设计模式方面我不太懂,说不出什么的。有些地方,可能描述的不太清晰,这些地方,你自己多多想想,多写代码测试,应该能帮助理解的。
      

  4.   


    嗯。其实对这个call不是很理解,那请问下
    其实
    function Subtype(name ,age){
    this.age = age;
    SuperType.call(this,name);
    }//上面的这个函数是不是可以用下面的来理解呢?两者在执行后是不是效果也一样的?
    function SubType (name ,age){
        this.name = name;
        this.colors = ["red","blue","green"];
        this.age = age;
    }
    还有一个问题就是你上面提到的我在构造函数里没写那几个属性,是不是指的比如SuperType中应有的有name 和color属性?我刚看了下这个函数貌似没有,不晓得我看的方式有没有错,或者是我理解的有问题。我的理解是在构造函数里的属性在他实例化的时候,会在实例中体现==
    谢谢你的解答call函数的第一个参数是传递给调用函数的上下文,把this作为第一个参数传递意思就是在调用的地方把this指向的函数上下文传递给被调用的函数,说简单点就是把一个对象作为this传递到被调用函数中实现动态添加属性方法的功能。函数从第二个参数开始的传递参数就是被调用函数的参数。
    你写的俩个函数执行的效果是一样的
      

  5.   

    前段时间在考试。没时间看,今天又有个问题,不知道方便问下不http://bbs.csdn.net/topics/390699880