Two ways of constructing an object in Javascript - javascript

function Person(age,name){
this.name = name;
this.age = age;
this.speak = function(){...}
}
function Person(age,name){
var p = {}
p.name = name;
p.age = age;
p.speak = function(){...}
return p;
}
The only difference I see is that using the first one you must call with new to let the language know its constructing a new object, is it essentially just constructing an object where 'this' refers to the new object being created??
i.e same as doing this.
{
age: 12,
name: "mark",
speak: function(){...}
}
where as the second returns an object so you can just write
Person(12,"mark")
instead of
new Person(12,"mark")
So I guess my question is, is there anything wrong with using the second version and are the differences I stated correct and are they the only differences between the two?

The first one:
function Person(age,name){
this.name = name;
this.age = age;
this.speak = function(){...}
}
Is a named constructor function.
Will work properly with instanceof Person
Is easier to do mixins or classic Javascript inheritance with
Could use the prototype for methods which may consume less memory or be faster to construct an object if there are lots of methods
Could also be designed to work without requiring new.
Is more akin to how the new ES6 class and extends syntax works which is likely how a lot of Javascript will be written in the future.
The second one:
function Person(age,name){
var p = {}
p.name = name;
p.age = age;
p.speak = function(){...}
return p;
}
Is a factory function. It creates a generic object, assigns properties to it and then returns the object.
It could be inherited from, but not in a classic way only by another factory function that knows how this object works. Some types of inheritance of mixins are not as doable with this structure.
Will not work with instanceof.
Does not and cannot use the prototype for methods.
Could be called with new and would still work (the system-created new object would just be discarded).
Can create any kind of object. It can even branch based on the arguments passed or environment and create a different kind of object based on some logic. Technically you can do this with the first style too, but it's inefficient because the interpreter creates a specific type of object and then you would return something else causing the original object that was created to then be garbage collected. So, if you're going to create multiple different kinds of objects, the second method would be more efficient at that.
Outside of these differences, the two will mostly function the same and there is nothing technically "wrong" with either method.
There are advocates for both styles of programming in Javascript and some would say there are situations where one is more appropriate than another and vice versa. I'd suggest you build a couple subclasses for this object to flush out some more of the programming differences because the subclasses will also work differently.
If you want to search for other articles on the topic, this is basically a "constructor function vs. a factory function in Javascript" which will sometimes stray into the argument for/against using the .prototype, but also tends to cover your topic too.
Here's are some articles on that specific topic (which cover a gamut of opinions):
JavaScript Constructor Functions Vs Factory Functions
Javascript object creation patterns
In defense of JavaScript’s constructors
Constructor function vs Factory functions
Factory constructor pattern
Some Useful JavaScript Object Creation Patterns
Constructors Are Bad For JavaScript
Constructors vs factories

Related

Difference between Factory function and Constructor [duplicate]

Can someone clarify the difference between a constructor function and a factory function in Javascript.
When to use one instead of the other?
The basic difference is that a constructor function is used with the new keyword (which causes JavaScript to automatically create a new object, set this within the function to that object, and return the object):
var objFromConstructor = new ConstructorFunction();
A factory function is called like a "regular" function:
var objFromFactory = factoryFunction();
But for it to be considered a "factory" it would need to return a new instance of some object: you wouldn't call it a "factory" function if it just returned a boolean or something. This does not happen automatically like with new, but it does allow more flexibility for some cases.
In a really simple example the functions referenced above might look something like this:
function ConstructorFunction() {
this.someProp1 = "1";
this.someProp2 = "2";
}
ConstructorFunction.prototype.someMethod = function() { /* whatever */ };
function factoryFunction() {
var obj = {
someProp1 : "1",
someProp2 : "2",
someMethod: function() { /* whatever */ }
};
// other code to manipulate obj in some way here
return obj;
}
Of course you can make factory functions much more complicated than that simple example.
One advantage to factory functions is when the object to be returned could be of several different types depending on some parameter.
Benefits of using constructors
Most books teach you to use constructors and new
this refers to the new object
Some people like the way var myFoo = new Foo(); reads.
Drawbacks
Details of instantiation get leaked into the calling API (via the new requirement), so all callers are tightly coupled to the constructor implementation. If you ever need the additional flexibility of the factory, you'll have to refactor all callers (admittedly the exceptional case, rather than the rule).
Forgetting new is such a common bug, you should strongly consider adding a boilerplate check to ensure that the constructor is called correctly ( if (!(this instanceof Foo)) { return new Foo() } ). EDIT: Since ES6 (ES2015) you can't forget new with a class constructor, or the constructor will throw an error.
If you do the instanceof check, it leaves ambiguity as to whether or not new is required. In my opinion, it shouldn't be. You've effectively short circuited the new requirement, which means you could erase drawback #1. But then you've just got a factory function in all but name, with additional boilerplate, a capital letter, and less flexible this context.
Constructors break the Open / Closed Principle
But my main concern is that it violates the open/closed principle. You start out exporting a constructor, users start using the constructor, then down the road you realize you need the flexibility of a factory, instead (for instance, to switch the implementation to use object pools, or to instantiate across execution contexts, or to have more inheritance flexibility using prototypal OO).
You're stuck, though. You can't make the change without breaking all the code that calls your constructor with new. You can't switch to using object pools for performance gains, for instance.
Also, using constructors gives you a deceptive instanceof that doesn't work across execution contexts, and doesn't work if your constructor prototype gets swapped out. It will also fail if you start out returning this from your constructor, and then switch to exporting an arbitrary object, which you'd have to do to enable factory-like behavior in your constructor.
Benefits of using factories
Less code - no boilerplate required.
You can return any arbitrary object, and use any arbitrary prototype - giving you more flexibility to create various types of objects which implement the same API. For example, a media player that can create instances of both HTML5 and flash players, or an event library which can emit DOM events or web socket events. Factories can also instantiate objects across execution contexts, take advantage of object pools, and allow for more flexible prototypal inheritance models.
You'd never have a need to convert from a factory to a constructor, so refactoring will never be an issue.
No ambiguity about using new. Don't. (It will make this behave badly, see next point).
this behaves as it normally would - so you can use it to access the parent object (for example, inside player.create(), this refers to player, just like any other method invocation would. call and apply also reassign this, as expected. If you store prototypes on the parent object, that can be a great way to dynamically swap out functionality, and enable very flexible polymorphism for your object instantiation.
No ambiguity about whether or not to capitalize. Don't. Lint tools will complain, and then you'll be tempted to try to use new, and then you'll undo the benefit described above.
Some people like the way var myFoo = foo(); or var myFoo = foo.create(); reads.
Drawbacks
new doesn't behave as expected (see above). Solution: don't use it.
this doesn't refer to the new object (instead, if the constructor is invoked with dot notation or square bracket notation, e.g. foo.bar() - this refers to foo - just like every other JavaScript method -- see benefits).
A constructor returns an instance of the class you call it on. A factory function can return anything. You would use a factory function when you need to return arbitrary values or when a class has a large setup process.
A Constructor function example
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("Jack");
new creates an object prototyped on User.prototype and calls User with the created object as its this value.
new treats an argument expression for its operand as optional:
let user = new User;
would cause new to call User with no arguments.
new returns the object it created, unless the constructor returns an object value, which is returned instead. This is an edge case which for the most part can be ignored.
Pros and Cons
Objects created by constructor functions inherit properties from the constructor's prototype property, and return true using the instanceOf operator on the constructor function.
The above behaviors can fail if you dynamically change the value of the constructor's prototype property after having already used the constructor. Doing so is rare, and it can't be changed if the constructor were created using the class keyword.
Constructor functions can be extended using the extends keyword.
Constructor functions can't return null as an error value. Since it's not an object data type, it is ignored by new.
A Factory function example
function User(name, age) {
return {
name,
age,
}
};
let user = User("Tom", 23);
Here the factory function is called without new. The function is entirely responsible for the direct or indirect use if its arguments and the type of object it returns. In this example it returns a simple [Object object] with some properties set from arguments.
Pros and Cons
Easily hides the implementation complexities of object creation from the caller. This is particularly useful for native code functions in a browser.
The factory function need not always return objects of the same type, and could even return null as an error indicator.
In simple cases, factory functions can be simple in structure and meaning.
Objects returned do not generally inherit from the factory function's prototype property, and return false from instanceOf factoryFunction.
The factory function can't be safely extended using the extends keyword because extended objects would inherit from the factory functions prototype property instead of from the prototype property of the constructor used by the factory function.
Factories are "always" better. When using object orientated languages then
decide on the contract (the methods and what they will do)
Create interfaces that expose those methods (in javascript you don't have interfaces so you need to come up with some way of checking the implementation)
Create a factory that returns an implementation of each interface required.
The implementations (the actual objects created with new) are not exposed to the factory user/consumer. This means that the factory developer can expand and create new implementations as long as he/she doesn't break the contract...and it allows for the factory consumer to just benefit from the new API without having to change their code...if they used new and a "new" implementation comes along then they have to go and change every line which uses "new" to use the "new" implementation...with the factory their code doesn't change...
Factories - better than all anything else - the spring framework is completely built around this idea.
Factories are a layer of abstraction, and like all abstractions they have a.cost in complexity. When encountering a factory based API figuring out what the factory is for a given API can be challenging for the API consumer. With constructors discoverability is trivial.
When deciding between ctors and factories you need to decide if the complexity is justified by the benefit.
Worth noting that Javascript constructors can be arbitrary factories by returning something other than this or undefined. So in js you can get the best of both worlds - discoverable API and object pooling/caching.
I think the factory function is superior to the constructor function. Using new with the constructor function, we are binding our code to one specific way of creating an object, while with a factory, we are free so we can create more different instances without binding ourselves. Let's say we have this class:
const file = new CreateFile(name)
If we want to refactor CreateFile class, creating subclasses for the file format our server supports, we can write an elegan factory function:
function CreateFile(name) {
if (name.match(/\.pdf$/)) {
return new FilePdf(name);
} else if (name.match(/\.txt$/)) {
return new FileTxt(name);
} else if (name.match(/\.md$/)) {
return new FileMd(name);
} else {
throw new Error("Not supprted file type");
}
}
with factory functions, we can implement private variables, hide the information from the users which is called encapsulation.
function createPerson(name) {
const privateInfo = {};
// we create person object
const person = {
setName(name) {
if (!name) {
throw new Error("A person must have a name");
}
privateInfo.name = name;
},
getName() {
return privateInfo.name;
},
};
person.setName(name);
return person;
}
For the differences, Eric Elliott clarified very well,
But for the second question:
When to use one instead of the other?
If you are coming from the object-oriented background, Constructor function looks more natural to you.
this way you shouldn't forget to use new keyword.

Can we assign a public method inside a object constructor ? (javascript)

I am reading about prototypes in javascript, In a article http://phrogz.net/js/classes/OOPinJS.html I read that we can not assign public methods inside a object constructor in javascript ? How prototypal methods are different from static methods and what are the advantage of using them ?
I read that we can not assign public methods inside a object constructor in javascript?
Yes, the article refers to this:
function MyObj(name)
{
this.name = name;
}
MyObj.prototype.sayHello = function() {
alert('hello ' + this.name);
}
new MyObj('world').sayHello();
As you can see, the public method sayHello() is declared in the prototype, which is done outside of the constructor. This is just how JavaScript works.
How prototypal methods are different from static methods and what are the advantage of using them ?
Prototypal methods are only "attached" to objects. For static methods you need to use this construct:
var MyStaticThing = {
name: 'world',
sayHello: function() {
alert('hello ' + this.name);
}
}
MyStaticThing.sayHello();
JavaScript isn't really well suited for most OOP concepts and paradigms, especially once you try to emulate inheritance. Rather than think of prototype vs "privileged" methods in OOP terms, you should think of things in terms of how JavaScript instantiates objects. Take this simple "class":
var id = 0;
function myClass()
{
var that = this;
id++; //closure, each new instance gets a unique id
this.id = id;
this.toString = function()
{
return that.id.toString();
}
}
And this class is instantiated like so:
var classInstance = new myClass();
This isn't a pattern I would necessarily recommend, the point is to illustrate that for each instantiation, each instance gets its own unique toString function. That means if you instantiate 100 classInstances, and you change toString on one of them to do something else, only that one instance will have that new functionality.
That also means that for every instance, every privileged method is also instantiated alongside with it. If you are instantiating a lot of instances, that can make a big performance difference. I had a case where I saw a measurable speed improvement by converting my privileged methods to prototype methods.
Speaking of prototype methods, here's what that might look like:
var id = 0;
function myClass()
{
id++; //closure, each new instance gets a unique id
this.id = id;
}
myClass.prototype.toString = function()
{
return this.id.toString();
}
In this case no matter how many myClasses you have, you only instantiate the toString method once. And if it changes, it changes for all myClasses.
Personally, I use privileged methods in most of my JavaScript classes because it looks cleaner and only bother with the prototype chain if I know it's going to be instantiated a huge number of times. Also being able to access private variables allows you to have some semblance of information hiding vs being forced to make any accessed variables public.
"the advantage of using them"...which one are you referring? Generally the advantage is going to be using a prototypal method (and object construction generally), over something like static or classical methods in javascript. The answer you are looking for is really too long to address here, but the short answer is that javascript is based off a prototypal object inheritance system (meaning objects can be created on the fly and may inherited one to the other), as opposed to a classical system (objects may only inherit from classes, i.e. Java, C++, etc.)
While you may create objects in javascript in a classical way -- because the language is that flexible -- it is a bad and confused way to do it. Prototypical object construction allows you do important and good things like data hiding, access to super methods, etc. Like I said this is a verbose subject, really to big to be taken on in a little text box.

What are the differences between these three patterns of "class" definitions in JavaScript?

Are there any important/subtle/significant differences under the hood when choosing to use one of these four patterns over the others? And, are there any differences between the them when "instantiated" via Object.create() vs the new operator?
1) The pattern that CoffeeScript uses when translating "class" definitions:
Animal = (function() {
function Animal(name) {
this.name = name;
}
Animal.prototype.move = function(meters) {
return alert(this.name + (" moved " + meters + "m."));
};
return Animal;
})();
and
2) The pattern that Knockout seems to promote:
var DifferentAnimal = function(name){
var self = this;
self.name = name;
self.move = function(meters){
return alert(this.name + (" moved " + meters + "m."));
};
}
and
3) a similar, simple pattern I've often seen:
var DifferentAnimalWithClosure = function(name){
var name = name;
var move = function(meters){
};
return {name:name, move:move};
}
and
4) The pattern that Backbone promotes:
var OneMoreAnimal= ClassThatAlreadyExists.extend({
name:'',
move:function(){}
});
Update 1: Changed pattern #2 and added pattern #3 in response to Elias' response // minor formatting
Just to be clear: JS doesn't know of classes, just objects and custom, self-defined constructor functions, but that's besides the point.
To answer your question in short: yes, there are some small and even some fairly large differences between the various ways of creating a new object you're posting here.
CoffeeScript:
This is actually the most clear-cut and traditional way to create your own constructor, but it has been "optimized" in the sense that it's been ready set-up to use (optional) closure variables.
Basically, what this code does, is use an IIFE, to wrap both the constructor definition and the proptotype method assignments in their own, private scope, that returns a reference to the new constructor. It's just clean, simple JS, no different from what you might write yourself.
Knockout:
Now this threw me a little, because to me, at least, the snippet you provide looks either like part of a module pattern, or a power constructor. But since you're not using strict mode, omitting the new would still make for dangerous situations, and since the entire function goes trough the trouble of creating a new instance of DifferentAnimal, only to then construct a second object literal, assigning all properties of DifferentAnimal to that secondary object, I'd say you're missing something. Because, truth be told, omitting the last return {}; statement here, would probably make no difference at all. Plus: as you can see, you're declaring a method (move) in what is, in essence, a constructor. This means that every instance will be assigned its own function object move, rather then getting it from the prototype.
In short: have another close look at where you got this snippet from, and double-check if this is the full version, because if it is, I can only see arguments against this.
Using a variable, defined inside the constructor is simply: a closure, suppose your properties have a distinct initial state, determined by some arguments, passed to that constructor:
function MyConstructor(param)
{
var paramInit = param/2;//or something
this.p = paramInit;//this property can change later on, so:
this.reInit = function()
{//this method HAS to be inside constructor, every instance needs its own method
this.p = paramInit;//var paramInit can't, it's local to this scope
};
}
var foo = new MyConstructor(10);
console.log(foo.p);//5
foo.p = 'hi';
console.log(foo.p);//hi
foo.reInit();
console.log(foo.p);//5
console.log(foo.paramInit);//undefined, not available outside object: it's a pseudo-private property
That's all there is too it, really. When you see ppl using var that = this; or something, that's often to create a reference to the main object that is available anywhere, without having to deal with the headaches of this (what does this reference? What should the method do when applied to an object other than the one it was originally intended for? etcetera...)
Backbone:
Here, we're dealing with another case: extending objects (IE: using methods, properties of either an existing "class" (constructor) or a particular instance) is not the same as simply creating an object.
As you well know, JS objects can be assigned new properties at any given time. Those properties can be removed, too. Sometimes, prototype properties can be redefined on the instance itself (masking the prototypal behaviour) etc... So it all depends on what you want the resulting object (the newly created object, that extends the given instance) to look like: do you want it to take all properties from the instance, or do you want both objects to use the same prototype somewhere down the line?
Both of these things can be achieved by using simple JS, too, but they just take a bit more effort to write yourself. However, if you write, for example:
function Animal(name)
{
this.name = name;
}
Animal.prototype.eat= function()
{
console.log(this.name + ' is eating');
};
That could be deemed the equivalent of writing:
var Animal = Object.extend({name:'',eat:function()
{
console.log(this.name + ' is eating');
}});
A lot shorter, but lacking the constructor.
new vs Object.create
Well, that's an easy one: Object.create just is a lot more powerful that new: you can define prototype methods, properties (including weather or not they are enumerable, writeable etc...) right at the time you need to create an object, instead of having to write a constructor and a prototype, or create an object literal and mess around with all those Object.defineProperty lines.
The downsides: Some people still aren't using ECMA5 compliant browsers (IE8 is still not quite dead). In my experience: it does become quite hard to debug sizeable scripts after a while: though I tend to use power-constructors more than I do regular constructors, I still have them defined at the very top of my script, with distinct, clear and quite descriptive names, whereas object-literals are things I just create "on-the-fly". Using Object.create, I noticed I tend to create objects that are really a little too complex to qualify as actual object literals, as though they are object literals:
//fictional example, old:
var createSomething = (function()
{
var internalMethod = function()
{//method for new object
console.log(this.myProperty || '');
};
return function(basedOn)
{
var prop, returnVal= {};
returnVal.myProperty = new Date();
returnVal.getCreated = internalMethod;//<--shared by all instances, thx to closure
if (!basedOn || !(basedOn instanceof Object))
{//no argument, or argument is not an object:
return returnVal;
}
for (prop in basedOn)
{//extend instance, passed as argument
if (basedOn.hasOwnProperty(prop) && prop !== '_extends')
{
returnVal[prop] = basedOn[prop];
}
}
returnVal._extends = basedOn;//<-- ref as sort-of-prototype
return returnVal;
};
}());
Now this is pretty verbose, but I've got my basic constructor ready, and I can use it to extend an existing instance, too. It might seem less verbose to simply write:
var createSomething = Object.create(someObject, {getCreated:function()
{
console.log(this.myProperty);
},
myProperty:new Date()});
But IMO, this makes it harder on you do keep track of what object is created where (mainly because Object.create is an expression, and will not be hoisted.Ah well, that's far from a conclusive argument of course: both have their pro's and con's: I prefer using module patters, closures and power constructors, if you don't that's just fine.
Hope this cleared up a thing or 2 for you.
The first example puts the move function in the prototype which will be shared between all Animal instances.
The second example creates a new move function for every the animal instance.
The third example generates a Animal class with the move function in the prototype similar to the first example but with allot less code.
(In your example the name is also shared between all instances, which you probably don't want)
Putting the function in the prototype makes instantiating Animals faster, and because of the way JIT engines work even the execution of the function is faster.

If Javascript's native OOP is classless, what about the constructor? Doesn't that imply a class?

I think Javascript native OOP system is said to be classless, and is object-based, not class-based. But every example I see always start with a constructor similar to
function Person(name) {
this.name = name;
}
Just by using a constructor this way, doesn't this already imply a class is being used? (a class called Person)
Details:
If we can use
a.__proto__ = b;
on any Javascript platform, then I think it is classless. But we can't do that. If we want that behavior, we need to use
function F() { }
F.prototype = b;
a = new F();
and so, a constructor has to be used. So if constructor is such a cornerstone in Javascript, that means it is intended to be constructor of Person, Widget, etc, and these are classes.
The OOP in Javascript is slightly different from, for instance, the Java OOP.
The Javascript constructors do not refer to a class definition (so it is classless). Rather the constructor refers to a prototype. The base of the OOP in Javascript is the Object object (not the Object class), from where all the others objects are derived.
Prototyping grants you inheritance, and the possibility to extend an existing object with properties and methods.
I suggest you this article.
In your example:
function Person(name) {
this.name = name;
}
Mike = new Person('Mike');
the Person() function lets you create a new object prototyped on the Object object with a new property called name. Well, such a kind of function in Javascript oop is called a constructor.
Classless may be an inaccurate way to describe JavaScript's approach on OOP.
JavaScript does lack class definitions.
It also lacks a class-to-object correspondence.
You can't check if an object instantiated with a constructor such as Person is of class Person.
You can check if it contains the expected object members and conclude that it is of the expected class.
But if the object members have been changed along the way you're not going to get the desired/expected result.
TL;DR
JavaScript exposes constructors (appropriately named prototypes) as a manner in which you can define a template for constructing plain objects.
The important thing is that the end result of a prototype call is a plain object with some predefined members and not an object of a certain class .
It's good to think of javascript as a classless environment. If you think javascript classes you should be able to assume there's certain useful things you can do when there are classes and they're strictly enforced. However those certain useful things you cannot assume. The presence of something that looks like a constructor does not indicate you're creating a class.
For example, let's say you var dude = Person('Ashton Kutcher'). Now, when you dude instanceOf person, you get true. You assume you have the properties and methods of a person. What if some code comes along and says dude.personMethod = undefined. Now, while dude instanceOf person will still be true, the personMethod is no longer available.
You can think of javascript as having classes but it's a leaky abstraction. It's better to think of javascript as having a prototypal inheritance system when it comes to determining what something is and what you can expect of it.
More information here: http://javascript.crockford.com/prototypal.html
Create a class using the Object Constructor and prototyping can help us
in creating many instances of the class without redefining the object each time wee need it.
so in the above example
function Person(name)
{
this.name = name;
}
you can create two persons with different names.
example :
var personA = new Person();
personA.name = "james";
var personB = new Person();
personB.name = "Tom";
alert(personA.name + personB.name);
i suggest you reading this link will be helpful
http://www.javascriptkit.com/javatutors/oopjs2.shtml

borrowing costructors and prototype chain

in many books and online tutorial there are examples on passing data to a super-class
constructor via a borrowing method pattern:
var Parent = function(name)
{
this.name = name;
this.my_parent = "parent_property";
this.go = function()
{
alert("GO")
}
}
var Child = function(name)
{
this.name = name;
this.my_child = "child_property";
Parent.call(this);
alert(this.hasOwnProperty("go")) // HERE TRUE!!!
}
var ChildChild = function(name)
{
this.name = name;
this.su = function(){}
}
// PSEUDO CLASSICAL ECMA STANDARD
Child.prototype = new Parent("PARENT");
ChildChild.prototype = new Child("CHILD");
var c = new ChildChild("CHILDCHILD");
now my question is: is this correct? in that pattern the properties of the super-class
are copied into THIS but in a OOP system I think that those properties must be in its
super-class. Now BORROWING constructor is only another pattern to make a sort of inheritance so I could not use prototype and so all the chain superclass properties are
into the last child class...but I don't think it's efficient.
So, at end, how can I pass data to a super-class without that pattern?
Thanks
By calling .call() you don't inherit in the classical sense of the word instead you tell Child to apply Parents prototype onto itself and thus Child.prototype has cloned properties and methods from Parent. This has no issues performance wise whatsoever though so abandoning prototype for efficiency reasons is not a valid reason.
If I can be honest I think enforcing OO paradigms onto javascript is the biggest mistake a javascript developer can make. Much like having to learn to deal with immutability in functional programming trying to make javascript behave like classical OO will only work against you in the long run.
It doesn't answer your question but there's tons of different ways to apply a super functionality to javascript none of which I can recommend though as there's no definitive version that doesn't come with a downside somewhere down the line.
JavaScript has no inherent support for building inheritance hierachies. The JavaScript way of doing type extensions would be to add properties from the 'parent class' to the 'child class', ie
function Parent(foo) {
this.foo = foo;
}
Parent.prototype.sharedFoo = 'sharedFoo';
function Child(foo, bar) {
// call the parent constructor
Parent.call(this, foo);
this.bar = bar;
}
Child.prototype.sharedBar = 'sharedBar';
// copy the properties of the parent class
for(var prop in Parent.prototype) {
if(Parent.prototype.hasOwnProperty(prop))
Child.prototype[prop] = Parent.prototype[prop];
}
It's also easily possible to add true prototypical inheritance, for example like this.
Via use of the clone() function, it's now possible to let the prototype object of the 'child class' inherit from the prototype object of the 'base class':
function Parent(foo) {
this.foo = foo;
}
Parent.prototype.sharedFoo = 'sharedFoo';
function Child(foo, bar) {
// call the parent constructor
Parent.call(this, foo);
this.bar = bar;
}
// inherit from the parent class
Child.prototype = clone(Parent.prototype);
Child.prototype.sharedBar = 'sharedBar';
JavaScript is a prototype based, functional language that pretends to be the cousin of Java.
Here is a few key things about JavasSript:
Everything is an Object, including Functions
Object is more like Hash, it is a collection of key value pairs
prototype itself is Object as well
To answer your first question about performance of "borrowing" prototype:
Typically, a JavaScript class contains a collection of [name, function object] pairs. When you borrow the prototype of the parent class, you basically copy the values of the parent prototype object into child class's prototype object.
The copy is by reference, when the function is copied, the function code is not duplicated, only the reference is copied. This is similar to function pointers in C language.
Thus the only performance hit is the
duplication of the prototype object,
which takes very little memory.
To answer your second question of how to pass data to Parent Class in a clean way:
There are many libraries out there that has some OOP style inheritance already built in. You can roll your own as well, but that would not be trivial.
I recommend a framework called Joose.
It supports classes, inheritance, mixins, traits, method modifiers and more.
Stable and used in production environments.
Elegant, and will save you a lot of key strokes
Using Joose, parent constructors can be overridden
or augmented, and SUPER() or INNER()
methods will be provided to access the
original constructor, or the subclass
constructor.

Categories

Resources