5

I am learning JavaScript and found two ways of assigning prototype.

The first is A.prototype = B.prototype and the second is A.prototype = new B()

For example:

function A() {
  console.log("A!")
}

function B() {
  console.log("B!")
}

// First case
A.prototype = B.prototype;
a = new A();  // a instanceof A,B

// Second case
A.prototype = new B();
a = new A();  // a instanceof A,B
  1. Is there any difference and which way to prefer?
  2. Is there any other way to assign prototype?

Update:

As Felix Kling advised there is a third way to assign a prototype:

A.prototype = Object.create(B.prototype);
Dan D.
  • 73,243
  • 15
  • 104
  • 123

3 Answers3

3

It's just another technique.

A.prototype = B.prototype;

By doing this, any changes to the B prototype will also change the A prototype because they’re the same object, and that’s bound to have undesirable side effects.

 A.prototype = new B();

Using this , we're ALSO Achieving inheritance with prototypes.

We make a A a B by making the A prototype an instance of B.

Example #1 :

function A() {  console.log("A!")}
function B() {  console.log("B!")}
A.prototype = new B();
a = new A();    
B.bb=function (){alert('');}
console.log(a.bb()) //Uncaught TypeError: Object #<B> has no method 'bb' 

now look at this :

function A() {  console.log("A!")}
function B() {  console.log("B!")}
A.prototype = B.prototype;
a = new A();    
B.prototype.bb=function (){alert('');}
console.log(a.bb()) //does alert
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • In Google Chrome and in Firefox I have a instanceof B // true (in first case) – Iaroslav Karandashev Feb 04 '14 at 08:30
  • @yarix you're right. absolutly right. ( confused with `B`) . editing – Royi Namir Feb 04 '14 at 08:35
  • @RoyiNamir, your example makes no sense. in the first case, B.bb is not available even when you create an instance of B class. You've just created a static bb function of B type, that's all. The answer of Andrey is more correct. The difference is, in one case you inherit only methods, in the 2nd case you inherit both, state and functionality. – Alexandr Feb 08 '17 at 16:18
  • @Alexandr did you understand my answer ? In the first example I'm trying to show that even if you add props to the B function , it doesn't recognize it. as opposed to the second example where if I set B.proto.bb - then the change is visible – Royi Namir Feb 09 '17 at 07:41
  • @RoyiNamir,your example, as I understand it does not show the difference between A.prototype = new B(); and A.prototype = B.prototype; it is more about: B.bb=function (){alert('');} vs B.prototype.bb=function (){alert('');}. The first function is not visible anyway and it does not matter how A.prototype is defined. Change in your first example: A.prototype = new B(); line onto: A.prototype = B.prototype; like in the 2nd example. the console output of the 1st example will not change, you get the same error. – Alexandr Feb 14 '17 at 08:45
  • @RoyiNamir what you are showing is just function definition via prototype vs static functions in JS, that's all: function B(){} B.bb = function(){} var obj = new B(); b.bb(); You cannot invoke bb via b instance of B. – Alexandr Feb 14 '17 at 08:47
1

You can try to add something to B and you'll get the difference:

function A() {
  console.log("A!")
}

function B() {
  this.text = "aaa";
}

You will have:

// First case
A.prototype = B.prototype;
a = new A();  

// a --> {}


// Second case
A.prototype = new B();
a = new A();  // a instanceof A,B

// a --> { text="aaa" }
Stefan
  • 14,530
  • 4
  • 55
  • 62
Andrey
  • 5,906
  • 4
  • 24
  • 30
0

@Iaroslav Karandashev, the difference is in one case you inherit only functionality

A.prototype = B.prototype;

In another case you inherit both, state and functionality.

A.prototype = new B();

You may change slightly the first case, in order to have the same behavour:

// First case
function B() {
  console.log("B!")
}
//child:
function A() {
  console.log("A!")
  //invoke parent constructor:
  B.apply(this);
}

A.prototype = B.prototype;
a = new A();  // a instanceof A,B


// Second case
function B() {
  console.log("B!")
}
//child, you do not need to invoke constructor of base class:
function A() {
  console.log("A!")
}
//base class constructor is invoked here:
A.prototype = new B();
a = new A();  // a instanceof A,B
Alexandr
  • 9,213
  • 12
  • 62
  • 102