Javascript constructor inheritance helper

I am trying to create a helper method for constructor inheritance in JavaScript.

I have the following simple code:

function extend(parent, fn) {
    return function () {
        parent.call(this);
        fn.call(this);
        fn.prototype.constructor = parent;
    }
}

function foo() {
    var a = 1;
    this.getA = function () { return a; };
}

var bar = extend(foo, function () {
    var b = 2;
    this.getB = function () { return b; };
  });

var obj = new bar();
console.log(obj.getA()); //1
console.log(obj.getB()); //2

console.log(obj instanceof bar); //true
console.log(obj instanceof foo); //false

1) How to make the last line ( obj instanceof foo) equal to true?

2) What do you think of such a decision, is it too bad? Are there other options for achieving something like this?

http://jsfiddle.net/jC6uz/

EDIT: I finished implementing the "extension":

function extend(parent, fn) {
    var Class = function () {
        parent.call(this);
        fn.call(this);
    }
    Class.prototype = parent.prototype;
    Class.prototype.constructor = Class;
    return Class;
}

But now, how to return the " bar " when called obj.constructor.name?
http://jsfiddle.net/jC6uz/1/

EDIT 2: Another version that supports constructor options (not directly, but still possible) http://jsfiddle.net/jC6uz/3/

+4
2

MDN , , , :

function extend(parent, fn) {
    var newConstructor = function() {
        fn.call(this);
    }
    newConstructor.prototype = new parent();
    return newConstructor;
}

function foo() {
    var a = 1;
    this.getA = function () { return a; };
}

var bar = extend(foo, function () {
    var b = 2;
    this.getB = function () { return b; };
});

var obj = new bar();
console.log(obj.getA()); //1
console.log(obj.getB()); //2

console.log(obj instanceof bar); //true
console.log(obj instanceof foo); //true

: http://jsfiddle.net/jfriend00/efReT/


, , , .

FYI, Class javascript. "", javascript, . , , , , . JS ++, JS, , ++, , . , JS , - , . newConstructor Class , , JS .

+2

, . foo , Foo.

Child, , Parent.apply(this,arguements);. , Child , Parent.appy Child (. ).

, constuctor , (instanceof constructor , - Child) extend init, "".

- , , - , - .

var extend = function(source,target,arg){
  //source=Parent, target=Child
  //set prototype without createing a source
  //instance and without using Object.create
  var fn=function(){},ret;
  fn.prototype = source.prototype;
  target.prototype = new fn();
  //repair constructor
  target.prototype.constructor = target;
  //create instance
  ret = new target(arg);
  //add function to set source intance members
  ret.extend_init=function(arg){
    source.apply(this,arguments);
  };
  //set source intance members
  ret.extend_init(arg);
  //remove init
  delete ret.extend_init;
  return ret;
};
var Parent = function(arg){
  this.name=(arg && arg.name)? arg.name:undefined;
  this.age=(arg && arg.age)?arg.age:undefined;
};
Parent.prototype.whoAreYou = function(){
  return "I am "+this.name+" and I'm "+this.age+
    " years old.";
};
var Child = function(){
};

var t = extend(Parent,Child,{
  name: "t",
  age: 22});

console.log(t instanceof Child);//<=true
console.log(t instanceof Parent);//<=true
console.log(t.whoAreYou());//<=I am t and I'm 22 years old.

, , , , :

var extend = function(source,target){
  var fn=function(){},orgProto=target.prototype,
  thing;
  fn.prototype = source.prototype;
  //overwriting Child.prototype, usually you define inheritance
  //  first and add Child.prototype members after but when setting
  //  inheritance dynamic (not having Parent.apply(this,arguments in
  //  Childs body) the Child prototype get overwritten
  target.prototype = new fn();
  //adding the Child.prototype members
  for(thing in orgProto){
    if(orgProto.hasOwnProperty(thing)){
      target.prototype[thing]=orgProto[thing];
    }
  }
  target.prototype.constructor = target;
  target.prototype.extend_init=function(){
    source.apply(this,arguments);
    return this;
  };
  return target;
};
var Parent = function(arg){
  this.name=(arg && arg.name)? arg.name:undefined;
  this.age=(arg && arg.age)?arg.age:undefined;
};
Parent.prototype.whoAreYou = function(){
  return "I am "+this.name+" and I'm "+this.age+
    " years old.";
};
var Child = function(){
};
Child.prototype.something=22;
//namesAndAges could be JSON data containing
// hundreds or even thousands of items
namesAndAges = [
  {name:"1",age:1},
  {name:"2",age:2},
  {name:"3",age:3},
  {name:"4",age:4},
  {name:"5",age:5}
  //, and many many more
];
var constr=extend(Parent,Child);
var persons=[];
for(var i = 0,len=namesAndAges.length;i<len;i++){
  //Child may have constructor parameters so we pass the parameter
  // object to both Child and Parent
  persons.push(new constr(namesAndAges[i])
    .extend_init(namesAndAges[i]));
};
delete constr.prototype.extend_init;
console.log(persons);

, , , super, mix ins this : fooobar.com/questions/2287/...

+1

All Articles