Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript inheritance with Object.create()?

How do I inherit with the Object.create()? I tried these, but none are working:

var B = function() {};
var A = function() {};
A = Object.create(B);
A.prototype.C = function() {};

and

var B = function() {};
var A = function() {};
A.prototype.C = function() {};
A = Object.create(B);

and

var B = function() {};
A = Object.create(B);
var A = function() {};
A.prototype.C = function() {};

Nothing worked. How am I supposed to use this new Object.create()-function?

like image 895
Tower Avatar asked Jun 20 '10 16:06

Tower


People also ask

How does JavaScript create inheritance?

When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

What is the use of object create in JavaScript?

The Object. create() method creates a new object, using an existing object as the prototype of the newly created object.

Does object assign create a new object?

The Object. assign() invokes the getters on the source objects and setters on the target. It assigns properties only, not copying or defining new properties.

What is the difference between object create vs New?

The major difference is that Object. Create returns the new object while the constructor function return the constructor of the object or the object. This is due to the important difference that new actually runs constructor code, whereas Object. create will not execute the constructor code.


3 Answers

There are several ways of doing inheritance in JavaScript

Construction Inheritance. Used if you don't need to call supertype constructor:

function Rectangle(length, width) { 
    this.length = length;
    this.width = width;
}

Rectangle.prototype.getArea = function() {
    return this.length * this.width;
};

// inherits from Rectangle
function Square(size) { 
    this.length = size;
    this.width = size;
}

Square.prototype = Object.create(Rectangle.prototype);

var rect = new Rectangle(6, 8);
var square = new Square(10);

console.log(rect.getArea());                // 48
console.log(square.getArea());              // 100
console.log(rect instanceof Rectangle);     // true
console.log(rect instanceof Object);        // true
console.log(square instanceof Square);      // true
console.log(square instanceof Rectangle);   // true
console.log(square instanceof Object);      // true

Constructor Stealing. Used if need to call supertype constructor:

function Rectangle(length, width) { 
    this.length = length;
    this.width = width;
}

Rectangle.prototype.getArea = function() {
    return this.length * this.width;
};

// inherits from Rectangle
function Square(size) { 
    Rectangle.call(this, size, size);
}

Square.prototype = Object.create(Rectangle.prototype);

var rect = new Rectangle(6, 8);
var square = new Square(10);

console.log(rect.getArea());                // 48
console.log(square.getArea());              // 100
console.log(rect instanceof Rectangle);     // true
console.log(rect instanceof Object);        // true
console.log(square instanceof Square);      // true
console.log(square instanceof Rectangle);   // true
console.log(square instanceof Object);      // true
like image 83
Vlad Bezden Avatar answered Oct 18 '22 18:10

Vlad Bezden


Object.create() is used to inherit objects, not constructors like you're trying to do. It pretty much creates a new object with the old object set as its prototypal parent.

var A = function() { };
A.prototype.x = 10;
A.prototype.say = function() { alert(this.x) };

var a = new A();
a.say(); //alerts 10

var b = Object.create(a);
b.say(); //alerts 10
b.x = 'hello';
b.say(); //alerts 'hello'

And just to make sure b is not just a clone of a,

a.x = 'goodbye';
delete b.x;
b.say(); //alerts 'goodbye'
like image 44
Chetan S Avatar answered Oct 18 '22 16:10

Chetan S


The pattern I use for this is to wrap each type in a module, and expose create and prototype properties, like so:

var Vehicle = (function(){
        var exports = {};
        exports.prototype = {};
        exports.prototype.init = function() {
                this.mph = 5;
        };
        exports.prototype.go = function() {
                console.log("Going " + this.mph.toString() + " mph.");
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports;
})();

Then I can build derived types like so:

var Car = (function () {
        var exports = {};
        exports.prototype = Object.create(Vehicle.prototype);
        exports.prototype.init = function() {
                Vehicle.prototype.init.apply(this, arguments);
                this.wheels = 4;
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports; 

})();

with this pattern, each type has its own create() function.

like image 17
Sean McMillan Avatar answered Oct 18 '22 16:10

Sean McMillan