I came to a code that contains these lines
var data = function() {
function Metadata() { /*some initialization here*/ }
Metadata.prototype = Object.create(Backend.prototype);
Metadata.prototype.constructor = Metadata;
return Metadata;
}
I struggle to understand what is actually going on, and how to use the returning object. If I understand it correctly, data
will now be an object that should be initialized like this
var d = new data()
But I don't understand the following lines and why Object.create()
is used instead of the new
keyword:
Metadata.prototype = Object.create(Backend.prototype);
Metadata.prototype.constructor = Metadata;
What do they do? Are they necessary? And what is the difference between Object.create
and new
?
JavaScript is a prototype-based language.
It means that it don't use the class keyword as in other languages. Instead JavaScript use functions as classes.
In your example the data variable can be assimilated to a class:
var Data = function() { ... }
To create an instance of this class we use the new keyword assigning the result of type object to a variable.
var data = new Data()
Since ECMA Script 6 we can use the instantiation method Object.create()
that create an uninitiated object with the specified prototype object and properties. It takes in argument the object which should be the prototype of the newly-created object. (It also copy the constructor)
So the following lines are a way to make Metadata extending the Backend object and keeps its own constructor:
// Metadata extends Backend
Metadata.prototype = Object.create(Backend.prototype);
Metadata.prototype.constructor = Metadata;
But this code is not exactly equivalent to Metadata.prototype = new Backend();
. See this example:
//Base class
var Backend = function(){ this.publicProperty='SomeValue'; }
//Extension class 1
var Metadata1 = function() { }
Metadata1.prototype = Object.create(Backend.prototype);
Metadata1.prototype.constructor = Metadata1;
//Extension class 2
var Metadata2 = function() { }
Metadata2.prototype = new Backend();
/*
* Then the results are different (see code snippet at the end of this post)
*/
//result1 = 'undefined'
var data1 = new Metadata1();
var result1 = data1.publicProperty;
//result2 = 'SomeValue'
var data2 = new Metadata2();
var result2 = data2.publicProperty;
In fact both are very similar, the main difference is that new
keyword actually runs constructor code, whereas Object.create
will not execute code.
One other difference is that with Object.create
you can create an object that doesn't inherit from anything (Object.create(null)
).
Whereas if you do Metadata.prototype = null
the newly created object will inherit from Object.prototype
Note: In some older browser (IE8 and below) you can use this equivalent code to Object.create
:
Object.create = function(o){
function F(){}
F.prototype=o;
return new F();
}
Here is the working code snippet that shows the differences between the two approach
//Base class
var Backend = function(){ this.publicProperty='SomeValue'; }
//Extension class 1
var Metadata1 = function() { }
Metadata1.prototype = Object.create(Backend.prototype);
Metadata1.prototype.constructor = Metadata1;
//Extension class 2
var Metadata2 = function() { }
Metadata2.prototype = new Backend();
//result: 'undefined'
var data1 = new Metadata1();
$("#result1").text("result1: " + (typeof data1.publicProperty=='undefined' ? 'undefined' : data1.publicProperty));
//result: 'SomeValue'
var data2 = new Metadata2();
$("#result2").text("result2: " + (typeof data2.publicProperty=='undefined' ? 'undefined' : data2.publicProperty));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result1"></div>
<div id="result2"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With