0

I know you can have one javascript instantiated object inherit the prototype of another constructor with constructer.prototype.__proto__ = otherConstructer.prototype, but can you use the call method like this to do the same thing?:

function constructor () {
  otherConstructor.call(this);
}
user730569
  • 3,940
  • 9
  • 42
  • 68
  • Not sure, but `apply` may help. – Passerby Oct 10 '12 at 04:39
  • The `call` operator only sets the value of `this` within a function, it has nothing to do with inheritance (i.e. property resolution along the `[[Prototype]]` chain) or scope (i.e. identifier resolution on the scope chain). Ok, you didn't mention scope, but I thought I'd throw it in there. :-) – RobG Oct 10 '12 at 06:13

1 Answers1

1

No, the prototype can't be replaced except by referencing the object itself and directly replacing it with the __proto__ property, which doesn't exist in all implementations. Look at this sample code:

function B() {
    this.someValue = "BBB";
}
B.prototype.testfunc = function() {
    console.log("Called from B: someValue =" + this.someValue);
}

function A() {
  this.someValue = "AAA";
  return B.call(this);
}
A.prototype.testfunc = function() {
    console.log("Called from A: someValue =" + this.someValue);
}

var test = new A();
test.testfunc();

// Will output "Called from A: someValue =BBB"

As you can see, the B constructor is correctly called and the object setup is from B and not A, but nevertheless the object's prototype is still from A. You can, of course, replace individual functions:

test.testfunc = B.prototype.testfunc;
test.testfunc();

// Will output "Called from A: someValue =BBB"

If you want a great explanation of why this is so, check out the accepted answer to this question.

Edit: There is no association with B.prototype when an A object is created. If you changed the code so that A.prototype.testfunc is not defined, then even though the A constructor calls B, nevertheless calling test.testfunc() will result in an undefined exception.

Community
  • 1
  • 1
Ed Bayiates
  • 11,060
  • 4
  • 43
  • 62
  • Good example. But if `this.textfunc` were not defined in `B`, would if then be used from `A`? That is, does your example completely strip out everything on the `A` prototype, or does everything on the `B` prototype just override that on the `A` prototype? – user730569 Oct 10 '12 at 04:56
  • I assume you mean if A.prototype.testfunc wasn't defined, would it use it from B instead of the A prototype, and no, it won't. You get an undefined function when you try to call test.testfunc. There is no association with B.prototype when creating a new A object. – Ed Bayiates Oct 10 '12 at 04:59
  • Is there a good way to have one constructor completely inherit the prototype of another then? – user730569 Oct 10 '12 at 05:51
  • @AresAvatar—saying "B constructor is conrrectly called" is misleading. `B` is called as a function, so it just modifies the value of `this` it is given (an instance of `A` in your code), that's it. There is nothing special happening, the instances of `A` don't inherit anything from `B.prototype`. When you do `test.testfunc = B.prototype.testfunc`, that is simple assignment, the instance still doesn't "inherit" from `B.prototype`, it just has a property referencing the function directly. Modify `B.prototype.testfunc` and the instance still has the old function. – RobG Oct 10 '12 at 06:25
  • @RobG, you may disagree with the terminology, but I believe I've still made it clear what does and does not occur. Inheritance isn't built in to JavaScript and we simulate it with various means. My example was used to answer the OP's question. – Ed Bayiates Oct 10 '12 at 06:33
  • @AresAvatar—Javascript (i.e. ECMAScript) has "built–in" prototype inhertiance that is used for built–in and native objects. It can emulate other inheritance patterns with varying degrees of conformance, but generally that isn't useful. – RobG Oct 10 '12 at 07:06
  • @RobG - no idea what point you are trying to make here. As I said I was answering the OP's question and did answer it. – Ed Bayiates Oct 10 '12 at 15:08