Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem extending class with javascript object prototype

I have got this problem... B is a base class, and A is a derived class... Event though A is derived from B, various objects of A points to the same object of B.

I know i have assigned an object of B to the prototype of A to make A child of B.

But different objects of A, they should have different address space to hold the variables, right? Can you anyone correct this?

    function B(){

        this.obj = {};
    }

    function A(){

    }

    A.prototype = new B();

    var a = new A();
    var b = new A();
    var c = new A();

    console.log(a.obj == b.obj); //prints true
    console.log(a.obj === b.obj); //prints true

    a.obj.name = "stackoverflow";
    console.log(b.obj.name); //prints stackoverflow

What change should I make in this code so that gives me following result.

a.obj === b.obj  //must be false

a instanceof A;  //must be true
a instanceof B;  //must be true
like image 499
Software Enthusiastic Avatar asked Jun 29 '11 10:06

Software Enthusiastic


People also ask

How to extend a prototype of a class?

From the latest MDN documentation, the way to extend prototype is : function MyClass () { SuperClass.call (this); } // inherit one class MyClass.prototype = Object.create (SuperClass.prototype); // mixin another Object.assign (MyClass.prototype, { //... your own prototype ... }); // re-assign constructor MyClass.prototype.constructor = MyClass;

What is the best way to implement child prototype in JavaScript?

Your approach it is a good pure JavaScript approach. The only get away from tipping "Child.prototype" every time is to put it in a reference variable. var children = Child.prototype; children.init = function () { /*/someoverridecode*/} But you are still doing the Child.prototype behind this.

Is there a shorthand to avoid writing child prototype when overriding property?

Is there no shorthand to avoid writing "Child.prototype." when overriding a property (using a litteral maybe, like the Parent prototype is written). I know of J. Resig's Class/extend approach. But I'd rather use Javascript as the prototypical language it is, not make it work as a "class-like behaving class-less OO language".

Is JavaScript a class-based language?

JavaScript is a prototype-based and not a class-based language. Since ES6 added a class declaration to the language, JavaScript developers can create classes with an easier. However, the addition is only syntactical sugar over JavaScript’s prototype inheritance. In short, JavaScript Class won’t behave as you’d expect in class-based languages.


3 Answers

That's why you shouldn't have mutable values (particularly objects or arrays) on a prototype - the same value will be shared across all object instances and can be changed in any of them. Here you can avoid the problem by using Object.create that won't call the constructor of B when creating the prototype:

A.prototype = Object.create(B.prototype);

Constructor of A should then call the constructor of B for each new object:

function A() {
  B.call(this);
}

For browsers that don't support Object.create() you can emulate it as mentioned on http://javascript.crockford.com/prototypal.html.

like image 105
Wladimir Palant Avatar answered Sep 22 '22 05:09

Wladimir Palant


Values are assigned by reference, and since all instances of A use the same instance of B as their prototype, they all refer to the same 'B'.

So this is exactly what's expected here. One way to solve this, is to add (for instance) a 'initialize' method the B 'class', which you could then call from within the A constructor.

You can also not use 'new B()' to define the prototype, and use Object.create instead. Object.create does not call B's constructor, but you can then call the parent constructor from A.

function A() {
   B.call(this);
}
like image 43
Evert Avatar answered Sep 23 '22 05:09

Evert


This is a part of prototypes in Javascript, I suggest you read this excellent thread.

like image 34
Dhaivat Pandya Avatar answered Sep 20 '22 05:09

Dhaivat Pandya