简体   繁体   中英

Javascript Inheritance pattern. Feedback please?

I am just wondering if there is any drawbacks with the way I am tackling inheritance below ? Is there any memory leaks to consider, any more memory use than other inheritance patterns ? I prefer to code JavaScript with the "class" pattern below ( new ...() ) ... I find other inheritance patterns obtrusive, and just came up with this one...

Comments are appreciated!

// Class A
function A() {

  var that = this;

  that.hello = function() {

    return "HELLO";

  }

}

// Class B
function B() {
  var zuper = new A();
  var that = this;

  that.variable = "VARIABLE";

  zuper.bye = function () {

    return "BYE";
  }

  zuper.getVariable = function() { 
    return that.variable
  }

  return zuper;
}

var b = new B();
alert ( b.hello() ) // "HELLO"
alert ( b.bye() )   // "BYE"
alert ( b.getVariable() ) // "VARIABLE"

================================ EDIT ================================= I have revised my original way, and came up with this. Does this suffer from the same problem as the one before ( Two objects created when creating a B, ( A and B total) ) See apply call in beginning of B

// Class A
function A() {

  var that = this;
  that.publicProperty = "PUBLIC_PROPERTY";
  var privateProperty = "PRIVATE_PROPERTY";

  that.hello = function() {
    return "HELLO";
  }

  that.getPrivateProperty = function () {
     return privateProperty;
  }

  that.overrideThis = function() {
    return "NO_PLEASE_NO";
  }

}

// Class B
function B(a, b, c) {
  A.apply(this, arguments);

  this.variable = "VARIABLE";
  var privateVariable = "PRIVATE_VARIABLE";

  this.bye = function () {

    return "BYE";
  }

  this.getVariable = function() { 
    return this.variable
  }

  this.getPrivateVariable = function() { 
    return privateVariable;
  }

  this.getAandB = function() {
    return a + b;
  }

  this.getFromSuperPublicPropery = function() {
    return this.publicProperty;
  }

  this.overrideThis = function() {
    return "MUHAHAHA";
  }

}

var b = new B("aaa", "bbb");

alert ( b.hello() )        // "HELLO"
alert ( b.bye() )          // "BYE"
alert ( b.getVariable() )  // "VARIABLE"
alert ( b.getPrivateVariable() ) // "VARIABLE"'
alert ( b.getAandB() )           // "aaabbb"
alert ( b.getFromSuperPublicPropery() )  // "PUBLIC_PROPERTY"
alert ( b.getPrivateProperty() ) // "PRIVATE_PROPERTY"  
alert ( b.overrideThis() ) // MUAHAHAA  


function C() {
  A.apply(this, arguments);
}

var c = new C();
alert ( c.overrideThis() ) // "NO_PLEASE_NO"
alert ( c.bye() ) // Expecting an exception here! Correct!    

I think you should consider about prototypes in javascript. See this article - http://www.sitepoint.com/javascript-inheritance/ .

Like HungryMind explained what you have is not inheritance, its more like delegation. instanceof won't work for testing if it's a base class. If you prefer to create closure based objects (for private variables) instead, you're stuck with an in inheritance scheme that does not use the prototype.

See my post for what makes for correct inheritance in JS. http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html Not that you can't use any other scheme, but you shouldn't until you really understand how inheritance is meant to work in JS.

I'd suggest using the following pattern (in your example):

// A function to implement basic inheritance
function inherit(child, parent) {
  function F() {};
  F.prototype = parent.prototype;
  child.prototype = new F();
  // Reassign the original constructor, explained below
  child.prototype.constructor = child;
  // Maybe have a reference to parent prototype
  // child.superClass = parent.prototype;
}

// Class A
function A() {
}

A.prototype.hello = function() {
    return "HELLO";
}

// Class B
function B() {
    this.variable = "VARIABLE";    
}

inherit(B, A);

B.prototype.bye = function() {
    return "BYE";
}

B.prototype.getVariable = function() {
    return this.variable;
};


var b = new B();
alert ( b.hello() ) // "HELLO"
alert ( b.bye() )   // "BYE"
alert ( b.getVariable() ) // "VARIABLE"

//If you reassigned the original constructor to child, you can do the following
alert (b instanceof B); //true
alert (b instanceof A); //true

You could also override hello , as B.prototype.hello if you wished and it wouldn't reflect on the parent (object A) instances. This way you actually use prototypes to save duplicates of function definitions and ACTUALLY inherit properties, functions etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM