www.webdeveloper.com
Results 1 to 5 of 5

Thread: specifying prototype from within the constructor?

  1. #1
    Join Date
    Jan 2009
    Posts
    32

    specifying prototype from within the constructor?

    I'm trying to learn javascript inheritance and having a bit of a confusion within me brain. (yep, I read through http://www.crockford.com/javascript/inheritance.html and am still confused. He says not to use classical inheritance and I'm trying not to, as far as I understand...)

    I got a bunch of classes that all need to have some the same variables. Let's say they are one, two, three. I'm trying to avoid the following redundancy:
    Code:
    function b(one, two, three)
    {
      this.one = one;
      this.tow = two;
      this.three = three;
     // unique variables go here
    }
    function c(one, two, three)
    {
      this.one = one;
      this.two = two;
      this.three = three;
     // unique variables go here
    }
    function d(one, two, three)
    {
      this.one = one;
      this.two = two;
      this.three = three;
     // unique variables go here
    }
    I did something like this:
    Code:
    function a(one, two, three)
    {
      this.one = one;
      this.two = two;
      this.three = three;
    }
    function b()
    { // unique variables go here}
    
    b.prototype = new a("defaultOneValueForB", "defaultTwoValueForB", "defaultThreeValueForB");
    
    function c()
    { // unique variables go here}
    
    c.prototype = new a("defaultOneValueForC", "defaultTwoValueForC", "defaultThreeValueForC");
    
    function d()
    { // unique variables go here}
    
    c.prototype = new a("defaultOneValueForD", "defaultTwoValueForD", "defaultThreeValueForD");
    This works well in that each of the classes b,c, and d have their own defaults for those variables. But is what if I don't want to use defaults and want to pass in those variables into a, b, or c's constructor? Would I have to re-declare those variables in the constructor, thus eliminating the benifit of inheritance?

    In Java I would do something like this:

    Code:
    public abstract class A
    {
         // declare instance variables here
    
      public A(int one, int two, int three)
      {
         this.one = one;
         this.two = two;
         this.three = three;
      }
    }
    
    pubic class B extends A
    {
       public B()
       {
          this(1,2,3);
       }
       public B(int one, int two, int three)
       {
          super(one, two, three);
       }
    }
    
    //... and so on for C and D
    Is there any way to do something similar in javascript or is the first piece of code I posted the best way to do it in this language?

    Edit: Forgot to ask: is there a way to specify the prototype from within the constructor so that you have access to its variables?

    Thanks!

  2. #2
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,503
    Crockford has a page specifically discussing prototypal inheritance (http://javascript.crockford.com/prototypal.html). That's what you needed to read.

    We can use Crockford's prototypal inheritance method:
    Code:
    Object.prototype.beget = function () {
    	function F() {}
    	F.prototype = this;
    	return new F();
    };
    Using this, your code could work like this:
    Code:
    var a = {
    	one: "defaultOneValue",
    	two: "defaultTwoValue",
    	three: "defaultThreeValue"
    };
    
    var b = a.beget();
    var c = a.beget();
    
    b.one = "overriddenOneValue";
    c.three = "overriddenThreeValue";
    
    alert( b.one );
    alert( b.two );
    alert( b.three );
    
    alert( c.one );
    alert( c.two );
    alert( c.three );
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  3. #3
    Join Date
    Jan 2009
    Posts
    32
    Thanks for the response.

    Your example doesn't really do what I need, though. I'd like to be able to assign all needed values through the constructor and not one by one. Also, it makes the default values for b and c be the same.

    What I need is new b() to give me an instance of b w/ b-specific defaults, but
    b("oneCustom", "twoCustom", "threeCustom") to give me and instance of b w/ all three parameters non-default.

    I've come up w/ the following way to do it, but it doesn't use the prototype property:

    Code:
    function displayObject(obj, name)
    {
        var str = "OBJECT ";
        if(name)
          str += name;
        str += "\n";
        for(var i in obj)
          if(obj[i].constructor != Function)
            str += "\n" + i + " : " + obj[i];
    
        alert(str);
    }
    
    function A(one,two)
    {
      this.one = one;
      this.two = two;
    }
    
    function B(one, two)
    {
      if(arguments.length > 0)
        A.apply(this, arguments);
      else
        A.apply(this, new Array("B1Default", "B1Default"));
        
    
      this.three = "333";
    }
    
    function C(one, two)
    {
      if(arguments.length > 0)
        A.apply(this, arguments);
      else
        A.apply(this, new Array("C1Default", "C1Default"));
        
    
      this.four = "4444";
    }
    
    var bee = new B();
    var beeHive = new B("b1Custom", "b2Custom");
    var see = new C();
    var seeNoEvil = new C("c1Custom", "c2Custom");
    
    displayObject(bee, "bee");
    displayObject(beeHive, "beeHive");
    displayObject(see, "see");
    displayObject(seeNoEvil, "seeNoEvil");
    Are there any immediate problems that you can see w/ this way of doing things?

    Thanks!

    Edit:
    I notice that if A has a function assiged via a prototype:

    Code:
    A.prototype.blah = function()
    {
      alert("blah");
    }
    calling bee.blah(); doesn't work, unless I use prototype for B: B.prototype = new A();

    If I do both the apply method and the prototype would that be bad?
    Last edited by Creature; 02-19-2009 at 03:15 PM.

  4. #4
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,503
    If I do both the apply method and the prototype would that be bad?
    Well... sometimes that kind of organization can cause problems, which is why I prefer Crockford's technique. But your code, as it's written now, isn't one of those problematic cases, so you can get by doing it that way.
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  5. #5
    Join Date
    Jan 2009
    Posts
    32
    Cool. Thanks

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles