Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #17952 > unrolled thread

Does copying the prototype reference from another constructor function maintain the prototype chain?

Started byGGolf <invalid@invalid.com>
First post2013-01-05 12:39 +0530
Last post2013-01-05 13:23 -0800
Articles 8 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  Does copying the prototype reference from another constructor function maintain the prototype chain? GGolf <invalid@invalid.com> - 2013-01-05 12:39 +0530
    Re: Does copying the prototype reference from another constructor function maintain the prototype chain? JJ <jaejunks@nah.meh> - 2013-01-05 10:57 +0000
      Re: Does copying the prototype reference from another constructor function maintain the prototype chain? David Mark <dmark.cinsoft@gmail.com> - 2013-01-05 06:44 -0800
    Re: Does copying the prototype reference from another constructor function maintain the prototype chain? David Mark <dmark.cinsoft@gmail.com> - 2013-01-05 06:43 -0800
    Re: Does copying the prototype reference from another constructor function maintain the prototype chain? John G Harris <john@nospam.demon.co.uk> - 2013-01-05 15:53 +0000
      Re: Does copying the prototype reference from another constructor function maintain the prototype chain? David Mark <dmark.cinsoft@gmail.com> - 2013-01-05 08:51 -0800
    Re: Does copying the prototype reference from another constructor function maintain the prototype chain? Scott Sauyet <scott.sauyet@gmail.com> - 2013-01-05 12:25 -0800
    Re: Does copying the prototype reference from another constructor function maintain the prototype chain? Luc Yen <luc@goal.tw> - 2013-01-05 13:23 -0800

#17952 — Does copying the prototype reference from another constructor function maintain the prototype chain?

FromGGolf <invalid@invalid.com>
Date2013-01-05 12:39 +0530
SubjectDoes copying the prototype reference from another constructor function maintain the prototype chain?
Message-ID<kc8jjg$k07$1@speranza.aioe.org>
I've been a Javascript dabbler for a few years, and have just embarked 
on learning more advanced stuff.

I have the following question in a tutorial by John Resig:

At http://ejohn.org/apps/learn/#76, Resig mentions that only the 
following maintains the prototype chain:

Ninja.prototype = new Person();

However, I notice that even the following statement makes all the test 
statements pass:

Ninja.prototype = Person.prototype;

Does it mean that using "Person.prototype" can actually be used instead 
of "new Person()"?

[toc] | [next] | [standalone]


#17953

FromJJ <jaejunks@nah.meh>
Date2013-01-05 10:57 +0000
Message-ID<XnsA13FB75B242F1jj@0.0.0.55>
In reply to#17952
GGolf <invalid@invalid.com> wrote:
> I've been a Javascript dabbler for a few years, and have just embarked 
> on learning more advanced stuff.
> 
> I have the following question in a tutorial by John Resig:
> 
> At http://ejohn.org/apps/learn/#76, Resig mentions that only the 
> following maintains the prototype chain:
> 
> Ninja.prototype = new Person();
> 
> However, I notice that even the following statement makes all the test 
> statements pass:
> 
> Ninja.prototype = Person.prototype;
> 
> Does it mean that using "Person.prototype" can actually be used instead 
> of "new Person()"?

Yes.

"Ninja.prototype = Person.prototype;" does create prototype inheritance, 
but with only 2 levels: Person and Object. The inheritance from Ninja and 
Person is the exact same.

function Person(){}

function Ninja(){}
Ninja.prototype=new Person();

var ninjaNew=new Ninja();
console.log('ninjaNew');
console.log(
  ninjaNew.__proto__===Ninja.prototype
); //true
console.log(
  ninjaNew.__proto__.__proto__===Person.prototype
); //true
console.log(
  ninjaNew.__proto__.__proto__.__proto__===Object.prototype
); //true

Ninja.prototype=Person.prototype;
var ninjaProto=new Ninja();
console.log('ninjaProto');
console.log(
  ninjaProto.__proto__===Ninja.prototype
); //true
console.log(
  ninjaProto.__proto__===Person.prototype
); //true
console.log(
  ninjaProto.__proto__.__proto__===Person.prototype
); //false
console.log(
  ninjaProto.__proto__.__proto__===Object.prototype
); //true

[toc] | [prev] | [next] | [standalone]


#17955

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2013-01-05 06:44 -0800
Message-ID<6168e9d6-c6b7-469e-9441-074ef4f91722@w8g2000yqm.googlegroups.com>
In reply to#17953
On Jan 5, 5:57 am, JJ <jaeju...@nah.meh> wrote:
> GGolf <inva...@invalid.com> wrote:
> > I've been a Javascript dabbler for a few years, and have just embarked
> > on learning more advanced stuff.
>
> > I have the following question in a tutorial by John Resig:
>
> > Athttp://ejohn.org/apps/learn/#76, Resig mentions that only the
> > following maintains the prototype chain:
>
> > Ninja.prototype = new Person();
>
> > However, I notice that even the following statement makes all the test
> > statements pass:
>
> > Ninja.prototype = Person.prototype;
>
> > Does it mean that using "Person.prototype" can actually be used instead
> > of "new Person()"?
>
> Yes.
>
> "Ninja.prototype = Person.prototype;" does create prototype inheritance,
> but with only 2 levels: Person and Object. The inheritance from Ninja and
> Person is the exact same.
>

No, not exactly. Draw the chains for each pattern (or search the group
as we've been over this many times over the years).

[toc] | [prev] | [next] | [standalone]


#17954

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2013-01-05 06:43 -0800
Message-ID<73b1bbfe-a369-4065-814b-6553779685eb@d10g2000yqe.googlegroups.com>
In reply to#17952
On Jan 5, 2:09 am, GGolf <inva...@invalid.com> wrote:
> I've been a Javascript dabbler for a few years, and have just embarked
> on learning more advanced stuff.
>
> I have the following question in a tutorial by John Resig:
>
> Athttp://ejohn.org/apps/learn/#76, Resig mentions that only the
> following maintains the prototype chain:
>
> Ninja.prototype = new Person();

In short, Resig is clueless. The above line is BS and that pattern has
been copied and pasted and recommended incessantly since the dawn of
JS. His version is just ninja flavored. :)

Clone (search the group) the prototype of Person and reference that
result with Ninja.prototype. Typically you would then augment the
result to create a more specific constructor.


>
> However, I notice that even the following statement makes all the test
> statements pass:
>
> Ninja.prototype = Person.prototype;

What statements?

>
> Does it mean that using "Person.prototype" can actually be used instead
> of "new Person()"?

Used for what?

[toc] | [prev] | [next] | [standalone]


#17957

FromJohn G Harris <john@nospam.demon.co.uk>
Date2013-01-05 15:53 +0000
Message-ID<BLCGJUCmxE6QFwKF@J.A830F0FF37FB96852AD08924D9443D28E23ED5CD>
In reply to#17952
On Sat, 5 Jan 2013 at 12:39:34, in comp.lang.javascript, GGolf wrote:
>I've been a Javascript dabbler for a few years, and have just embarked 
>on learning more advanced stuff.
>
>I have the following question in a tutorial by John Resig:
>
>At http://ejohn.org/apps/learn/#76, Resig mentions that only the 
>following maintains the prototype chain:
>
>Ninja.prototype = new Person();
>
>However, I notice that even the following statement makes all the test 
>statements pass:
>
>Ninja.prototype = Person.prototype;
>
>Does it mean that using "Person.prototype" can actually be used instead 
>of "new Person()"?

Resig calls that page

   #76: The basics of how prototypal inheritance works

but I don't think he does that job at all well.

Doing
   Ninja.prototype = new Person();
is a confused thing to do. Ordinary objects, such as new Person(), and 
prototype objects, such as Ninja.prototype, have different jobs to do. 
An ordinary object's main job is to hold data; a prototype object's main 
job is to hold functions (methods).

These two jobs shouldn't be mixed together. Prototype objects should be 
built separately.

   John
-- 
John Harris

[toc] | [prev] | [next] | [standalone]


#17958

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2013-01-05 08:51 -0800
Message-ID<886949c9-7206-48d9-91ac-6bd2a02283d5@k6g2000yqf.googlegroups.com>
In reply to#17957
On Jan 5, 10:53 am, John G Harris <j...@nospam.demon.co.uk> wrote:
> On Sat, 5 Jan 2013 at 12:39:34, in comp.lang.javascript, GGolf wrote:
> >I've been a Javascript dabbler for a few years, and have just embarked
> >on learning more advanced stuff.
>
> >I have the following question in a tutorial by John Resig:
>
> >Athttp://ejohn.org/apps/learn/#76, Resig mentions that only the
> >following maintains the prototype chain:
>
> >Ninja.prototype = new Person();
>
> >However, I notice that even the following statement makes all the test
> >statements pass:
>
> >Ninja.prototype = Person.prototype;
>
> >Does it mean that using "Person.prototype" can actually be used instead
> >of "new Person()"?
>
> Resig calls that page
>
>    #76: The basics of how prototypal inheritance works
>

He calls a lot of things a lot of things, often inaccurately. :)

> but I don't think he does that job at all well.

When it comes to JS, it's hard to find a place for him. Really loud
village idiot comes to mind. :(

>
> Doing
>    Ninja.prototype = new Person();
> is a confused thing to do.

...And always has been. If only he would have picked up CLJ once in a
decade. Of course, he preferred to "ban" his followers from reading
about how clueless his code was (and still is, of course).

[toc] | [prev] | [next] | [standalone]


#17963

FromScott Sauyet <scott.sauyet@gmail.com>
Date2013-01-05 12:25 -0800
Message-ID<29e78b3b-bb92-4b6d-9090-63fe080a1194@4g2000yqv.googlegroups.com>
In reply to#17952
GGolf wrote:
> I've been a Javascript dabbler for a few years, and have just embarked
> on learning more advanced stuff.
>
> I have the following question in a tutorial by John Resig:
>
> At http://ejohn.org/apps/learn/#76, Resig mentions that only the
> following maintains the prototype chain:
>
> Ninja.prototype = new Person();
>
> However, I notice that even the following statement makes all the test
> statements pass:
>
> Ninja.prototype = Person.prototype;

Then there are some missing tests.


> Does it mean that using "Person.prototype" can actually be used instead
> of "new Person()"?

No.  Imagine this:

    var Person = function(name) {this.name = name;}
    Person.prototype.speak = function() {
      console.log(this.name + " says hi");
    }
    var Ninja = function(name) {Person.call(this, name);}
    Ninja.prototype = Person.prototype;
    var sue = new Person("Sue");
    var peg = new Person("Peg");
    sue.speak(); // "Sue says hi"
    peg.speak(); // "Peg says hi"

All well and good.  But now:

    Ninja.prototype.kill = function(target) {
      console.log(this.name + " kills " + target);
    }
    peg.kill("Bill"); // "Peg kills Bill";
    sue.kill("Joe"); // "Sue kills Joe"

But wait, Sue is not a Ninja.  She shouldn't have a `kill` method.
Sharing the prototype that way will cause this problem.

So the test suite is clearly missing something, if you pass all the
tests with this technique.

Using an object derived from the prototype of parent constructor as
the prototype for the child constructor is very much the usual
technique in Javascript.  There's often an additional step used, which
is to make this construction indirect by attaching the parent
prototype as the prototype of a throwaway function:

    var F = function() {};
    F.prototype = Person.prototype;
    Ninja.prototype = new F();

This sort of technique might be wrapped in a function if you're going
to use it, with a name like `extend` or `inherit`, possibly included
in some larger Object-Oriented library.

  -- Scott

[toc] | [prev] | [next] | [standalone]


#17965

FromLuc Yen <luc@goal.tw>
Date2013-01-05 13:23 -0800
Message-ID<f5f9f301-ae73-4acb-9ba8-e4843129c4bd@googlegroups.com>
In reply to#17952
GGolf於 2013年1月5日星期六UTC+8下午3時09分34秒寫道:
> I've been a Javascript dabbler for a few years, and have just embarked 
[...]
> Ninja.prototype = new Person();
> However, I notice that even the following statement makes all the test 
> statements pass:
> Ninja.prototype = Person.prototype;
> Does it mean that using "Person.prototype" can actually be used instead 
> 
> of "new Person()"?

The later construct has a problem. If you later extend new method for your ninjas

    Ninja.prototype.newMethod = function() {...}

It actually defined on Person's prototype and affect all your people instances. 
And think that if we have a SuperNinja that extends Ninja, you'll end up writing

    SuperNinja.prototype = Ninja.prototype; // Chaos, and again...
    NinjaMaster.prototype = SuperNinja.prototype; // Chaos

Now they point to the same Person.prototype(which in turn is a simple instance of Object).

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web