<script language="javascript">
function person(name){
this.name = name;
}
person.prototype.say = function(){alert("hello, i'm " + this.name);}function employee(name, salary){
person.call(this, name);
this.salary = salary;
}
employee.prototype = new person(); //等效于employee.prototype = person.prototypeemployee.prototype.showMoney = function(){alert(this.name + "'s salary is " + this.salary);}alert(employee.prototype == person.prototype);
alert(employee.prototype == person);
</script>
大家看上面的代码,是一个简单的继承,employee.prototype = new person();的目的是将employee的protoytype设置成person的prototype,从而可以通过“原型链”调用到person的prototype的方法,所以我觉得他等效于employee.prototype = person.prototype,但通过下面的两个alert来看,他们并不等效,请问它们的区别是什么,原因在哪里?

解决方案 »

  1.   

    employee.prototype 和 person.prototype 是两个完全不一样的对象怎么会一样。你看看他们的构造函数就知道了他们也有些自己的属性。你可以调试看看有些属性是完全不一样的。
      

  2.   

    你好,我的意思是employee.prototype = new person();和employee.prototype = person.prototype;是等效的吗?
      

  3.   

    http://www.cnblogs.com/winter-cn/archive/2009/05/16/1458390.html
    看看这个
      

  4.   


    当然不等效employee.prototype = new person() 这样的话person中this上的属性也会在employee.prototype而employee.prototype = person.prototype 而这样就只会有原型上的东西。 this上的没有。
     
      

  5.   

    prototype 是原型对象, 
    employee.prototype = new person();使得employee的实例拥有了person的所有属性,包括person.prototype里的所有属性,
    employee.prototype只是employee的原型对象,当js试图查找employee实例里的某一属性时会先查找 emloyee的实例成员,如果没找到会从employee.prototype里查找,然后person的实例, person.prototype...以此类推.employee.prototype  person.prototype  person
    是三个不同的概念, employee.prototype和person.prototype是Object, person是构造函数.所以他们之间不会相等!
      

  6.   

    我这样测试:
    var e = new employee("BillGates", 5000);
    alert(e.prototype.name);
    结果:
    Error:'e.prototype.name' 为空或不是对象
    汗 没看明白
      

  7.   

    new 就是无值的状态  点出来的是本身有值的状态  当然不一样了
      

  8.   

    你NEW 了一下 内存就是开辟了一个新的空间 它本身是不会和你THIS里的东西是一样的。但是THIS里面是有值的  NEW里面是新的空间所以是无值的
      

  9.   

    很明显的
    employee.prototype = new person();
    看上面 就知道下面不等了
    alert(employee.prototype == person.prototype);
    alert(employee.prototype == person);
      

  10.   

    不等效
    employee.prototype = new person();
    表示employee.prototype是person的实例。既employee.prototype.__proto__ = person.prototype
    employee.prototype里找某个属性或者方法时,首先从对象本身找(new person实例对象),找不到才根据隐式链__proto__(firefox可访问)指向,到person.prototype里去找,还找不到就到person.prototype.__proto__(也就是Object.prototype)去找,这么一层层往上找。
    你可以好好看下下面这张图,我贴了好多次了,转自cnblogs一位大牛riccc的图,红色部分就是__proto__链式指向
      

  11.   

    这张图是武功秘籍,好好看看,就知道所谓的prototype链到底是条什么样的链。无非就是规定对象之间互相如何关联的一条链状结构。
    给你好好说说//这个函数定义对应图上左边use(应该是user) defined functions那一层,用户定义函数
    function person(){
      
    }
    //同上
    function employee(){
    }
    //这个employee.prototype对应左边objects that(应该是those :D) created by user defined functions那一层
    employee.prototype = new person()然后你再看红色箭头指向,再结合我#13楼的描述。
      

  12.   

    楼上,那
    employee.prototype = new person();和employee.prototype = person.prototype;
    从实际应用的效果来说,其实也没什么大的区别喽!只是new person()的话就多了一层,但是从实际效果来看应该是没什么区别的吧?不知这样说对不对
      

  13.   

    图文并茂的说,怎么还是一样呢?
    再给你个例子function person(){
    this.feature = 'cruel animal';
    }
    person.prototype = {}
    function employee(){

    }
    //employee.prototype = person.prototype;
    employee.prototype = new person();//把这行注释掉,再把上面的打开,alert(rookie.feature);为什么会alert出undefined?请再仔细思考.
    var rookie = new employee();
    alert(rookie.feature);
      

  14.   

    楼上,你的这个例子给我的理解就是通过new person()的话,会继承person的所有属性包括构造函数中的,而使用person.prototype的话则只是继承了person的prototype下的东东,这样对不?
      

  15.   

    搞这么复杂干吗 从语法就能看出因为 employee.prototype = new person();  EP == NP 
    所以如果 employee.prototype == person.prototype 为真   EP == PP
    则证明 new person() == person.prototype          NP == PP
    但是 new person() == person.prototype 明显是不能相等的  NP==PP -->F
    所以反推 employee.prototype == person.prototype 为真是错误的  EP==PP -->F我也学楼上的 搞的复杂点
      

  16.   

    可以这么粗理解,实际上就是把employee.prototyp的隐性链(__proto__)指向给改动了.
    接17楼1.如果是
    employee.prototype = new person();
    var rookie = new employee();
    alert(rookie.feature);
    那么要找rookie.feature
    就循着这条链去找( -> 意为如果找不到则往下一个对象找)
    rookie(new employee) -> rookie.__proto__(employee.prototype,也就是new person) -> employee.prototype.__proto__
    (person.prototype) -> person.prototype.__proto__(Object.prototype)
    rookie.feature在这条链中的 employee.prototype处被找到,也就是第二步:rookie.__proto__2.如果是
    employee.prototype = person.prototype;
    var rookie = new employee();
    alert(rookie.feature);
    那么要找rookie.feature
    就循着这条链去找
    rookie(new employee) -> rookie.__proto__(employee.prototype,也就是person.prototype)
    -> employee.prototype.__proto__(Object.prototype)

    找不到,over.prototype就是一条链,一环扣一环.不用继承那种东西理解反而好些.
      

  17.   


    function person(name){
                this.name = name;
            }
            
            person.prototype.say = function(){
                alert("hello, i'm " + this.name);
            }

    var t=new person("fang");
    alert(t.name);
    t.say();
            
            function employee(name, salary){
                person.call(this, name);   
                this.salary = salary;
            }


    //并没有继承person.prototype中的say方法
    var tt=new employee("fang","1000");
    alert(tt.name);
    alert(tt.salary);

            //employee.prototype拥有属性name,方法say(),即拥有person及person.prototype中的所有方法和属性
            employee.prototype = new person(); 

    //此又增加了showMoney()方法
    /**因此employee.prototype有属性name,方法say(),showMoney()
       即拥有person及person.prototype中的所有方法和属性即employee.prototype
       对象中的属性和方法
     **/

            employee.prototype.showMoney = function(){
                alert(this.name + "'s salary is " + this.salary);
            }
        
    var ttt=new employee("fang","1000");
    employee.prototype.say();


    /* person.prototype中只有方法say()
     * person中有属性name和对象person.prototype,相当于person.prototype是person子集
     * employee.prototype=person+person.prototype+employee.prototype
     */

            alert(employee.prototype == person.prototype);
            alert(employee.prototype == person);
      

  18.   

    我找了找 觉得这篇讲得挺好
    http://blog.csdn.net/niuyongjie/archive/2009/11/15/4810835.aspx
      

  19.   

        javascript 难就难在我们已经学过了别的面向对象的语言。 我们总是试图用别的面向对象的语言来理解javascript。 其实javascript并不真正支持继承。 但是javascript却有模拟继承的能力。    javascript 的原型。 其实也是非常简单。首先原型prototype 他也是一个普通的对象,不要把他想的非常的深不可测, 呵呵.. 比如 function a(){ this.c=12 ;}; a.prototype.b=function(){alert(this.c)//12};var aa=new a(); aa.b(); 也就是说现在aa 他现在有了你给this关键字添加的属性 比如这里的this.c。也有了你给a.prototype 添加的属性a.prototype.b;当你通过aa.属性名 访问某个属性时,他们是有顺序的 先this上的然后prototype.   这样我们就产生了2种模拟继承方式: 即我们通过给this添加属性, 和给prototype添加属性.
     
     第一种:     function  a(){
             this.c=12;
          }      function b(){
                a.call(this);
          }
           
           var bb= new b(); alert(bb.c); //12 b继承了a 这种方式非常的巧妙, call 是Function原型的一个
    方法,意思也很简单 a.call(this); 就是说调用a方法,并把a方法里的this换成你给的参数 这里我们给的就是b中的this. 也就是说我们在new b()时我们调用了a方法  而a方法我们把他里面的this 换成了b方法里的this。
    这就相当于我们给b中的this添加了c这个属性,  所以我们bb就有c这个属性.  第二种:    function  a(){
             this.c=12;
             this.d=function(){
                 alert(this.c);
             }
          }      function b(){
              this.c=34;
          }
        var aa=new a();
       b.prototype=aa;  var bb=new b();
       
       bb.d();//34  为什么是34? 前面说过javascript 会先访问this里的然后访问prototype里的 在这里我们b.prototype=new a(); 很明显我们给b的prototype原型指向了一个对象,即aa;而aa是有d这个方法的。所以我们的bb也有了d这个方法. 但是这里为什么是34而不是12呢?简单的说  javascript中this的指向就是你调用一个方法时.(点) 前面的那个对象 。比如这里bb.d();我们这里d方法点前面是bb 所以this指向的就是bb这个对象,而bb我们设置了一个c的属性c=34  ;所以这里就弹出了34.当我们去点b方法中this.c=34时,结果就变成了12 这是为什么呢? 写的实在手痛了 这个问题就留给你回答吧。提醒(1: this是可以访问原型中的属性的,2:根据开始我对对象属性访问顺序的分析)     
          
      
      

  20.   

    lz,了解prototype,重点就是了解对象[[prototype]]也就是__proto__的指向。
    那个javascript对象模型图极其精炼啊,为什么不用心去看看呢?
    你理解了那张图,你就能理解下面这个例子//1
    Object.prototype.a = 'hello Object.prototype';
    //2
    Function.prototype.a = 'hello Function.prototype';function o(){

    }var t = new o();alert(t.a);//为什么是 hello Object.prototype ?
    alert(o.a);//为什么是 hello Function.prototype ?
      

  21.   

    例子再多点内容//1
    Object.prototype.a = 'hello Object.prototype';
    //2
    Function.prototype.a = 'hello Function.prototype';
    //3
    Object.prototype.b    = 'hello Object.prototype B';function o(){

    }var t = new o();alert(t.a);//为什么是 hello Object.prototype ?
    alert(o.a);//为什么是 hello Function.prototype ?
    alert(Function.a);//为什么是hello Function.prototype ? 
    alert(Object.a);//为什么是hello Function.prototype ? 
    alert(Object.b);//为什么是hello Object.prototype B ?
      

  22.   

    有误,sorry
    =======================
    重点就是了解对象属性[[prototype]]也就是__proto__的指向
      

  23.   

    楼上的讲得非常好现在我明白了,其实employee.prototype = new person();的目的是让employee的prototype继承person的prototype,从而使person的prototype成为employee的prototype的一部分,从而达到继承的效果,但是使用new的话会出现一个问题,即employee的prototype也会拥有person构造函数中的所有属性,例如我们可以这样访问person构造体中的属性:employee.prototype.name,虽然这不会影响什么,但我觉得还是没必要的,所以我觉得在继承prototype时采用employee.prototype = person.prototype;这样的方式是更适合的。不知各位高手是否同意
      

  24.   

    s_title 讲得非常好谢谢龙腾虎跃,我觉得我现在已经基本理解了,上面出现的问题我也都知道是什么原因了,只是还不够熟悉
      

  25.   

    老用继承的概念去理解prototype,到时候可能会有苦头吃的.呵呵.
    当然javascript的继承基本靠的是prototype链.
    你不想深究的话,那就这样吧.
      

  26.   


    这个我说的有误,不好意思,我现在并没用再用继承去理解js对象继承之间的关系了,知道js是通过prototype和call的传递this来模拟类的继承,而xx.prototype = new yy();时会使yy的prototype成为xx.prototype的一部分
      

  27.   

    这张图和我发那个差太远了,不够精炼.
    再说那张图不是我画的,是我以前跟你一样晕的时候,搜索到的
    原文在这里http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html
    看不懂不要紧,多看几遍,再慢慢体会那张图.你会有豁然开朗的感觉.再给你个例子,firefox(因为firefox下才可访问__proto__)下不用new,如何模拟实例化一个函数?
    只考虑了__proto__指向,把问题最简单化.
    //请在firefox下运行
    function init(fn){
    var o = {}
    o.__proto__ = fn.prototype;
    fn.call(o);
    return o;
    }
    var c = function(a,b){
    this.a = 'a';
    }
    c.prototype = {
    b : 'b'
    }var i = init( c );alert(i.b);//为什么能找到b这个属性?
      

  28.   

    接上面
    而使用xx.prototype = yy.prototype;的话,则会将xx的prototype完全指向成yy的prototype,所以,如果在xx.prototype = yy.prototype;之前有改变xx.prototype的操作的话,这之后都没丢失之前的操作
      

  29.   

    龙腾虎跃,下手真快//请在firefox下运行
    function init(fn){
        var o = {} //创建一个对象
        o.__proto__ = fn.prototype; //将对象o内置的原型对象设置为fn的prototype——__proto__被称为内置原型对象
        fn.call(o); //将o作为fn的this并调用fn
        return o;
    }
    var c = function(a,b){
        this.a = 'a';
    }
    c.prototype = {
        b : 'b'
    }var i = init( c );alert(i.b);//为什么能找到b这个属性?因为i=o
    且o.__proto__=c.prototype
    又因为c.prototype.b = 'b'
    所以o.__proto__.b=o.b=='b'
    所以i.b=='b'
    这样对不?
      

  30.   

    最好不要用你等于我,所以我等于你的方式去理解.
    alert(i.b)首先找i这个对象里有无b属性,没有就到i.__proto__去找,也就是fn.prototype,如果还找不到,就应该到
    fn.prototype.__proto__去找,也就是Object.prototype
      

  31.   

    其实都通了,我贴的图的inobj其实就是你说的__proto__,其它都没什么了
      

  32.   

          lz通了就好
    建议可以看看这2篇文章
    http://www.mscto.com/JavaScript/2009010343993.html 
    http://topic.csdn.net/u/20080714/10/cacb56ca-819d-48ff-adf6-7ffe9a13af5b.html相信会使楼主对javascript理解更上一层楼。