Parasitic Constructor Pattern can be seen as a combination of factory and constructor pattern.
In factory pattern, we call a function which then explicitly creates an object and adds desired properties and methods to the object and finally returns the object.
function createPerson(name, age, job){
var o = new Object(); //explicit object creation
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);
Things to note:
explicit object is created and returned
method and properties are added to the explicitly created object
method is called without new keyword
The disadvantage: it doesn’t allow to identify the type of the object.
Any function can be treated as constructor by calling it with new operator. When called without new operator, inside the function, this object points to the global object (window in browser). And when the function is called with the new operator, it first creates the new instance of object and then sets this object to a newly created object.
Constructor pattern adds methods and properties to this object and finally returns this object thus allowing to later identify the type of the object using instanceOf operator.
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
var person2 = new Person(“Greg”, 27, “Doctor”);
Things to note:
function is called with new operator (to make JavaScript engine treat it as a constructor)
object is not created explicit instead this object is returned
Now the Parasitic Constructor Pattern explicitly creates and returns an object similar to factory pattern and it is called with new operator like constructor pattern:
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var friend = new Person(“Nicholas”, 29, “Software Engineer”);
friend.sayName(); //”Nicholas”
However I can't see the use of calling the function with new operator. I mean since the function explicitly creates and returns the object we will not be able to identify the object type explicitly using instanceOf operator.
So what is great in Parasitic Constructor pattern? Is there any technical subtlety that can be exploited or suitably used for a specific object creation scenario? Or Is just another possible programmatic approach for creating object?
I think the part that you're skipping over with the Factory, is that in most other languages, the factory is either going to be making multiple different kinds of similar objects, whether done like:
var truck = carFactory("Truck");
var jeep = carFactory("Jeep");
or done like:
var piano = instrumentFactory.piano("Grand");
var bass = instrumentFactory.bass("Upright");
or any other interface you want it to have...
OR a factory's responsibility is going to be to make a very big class out of smaller classes, through dependency-injection, and potentially polymorphism:
function createTank (gunType) {
var armour = new Armour();
armour.hp = 120;
var wheels = new ChainTracks();
var driver = new Soldier();
driver.hp = 15;
var gun = gunFactory(gunType);
var tank = new Tank(armour, wheels, gun);
tank.driver = driver;
return tank;
}
var ground_tank = createTank("cannon");
var aa_tank = createTank("flak_cannon");
var at_tank = createTank("depleted_uranium_lancer");
If you have a Factory which is as simple as making an object, setting its properties and returning the object, then there really is no difference.
The differences come into play when you're either talking about using a lot of specialized components to make something come together (whether they're injected, or hard-coded), or you're dealing with inheritance.
And honestly, I'd suggest learning more about those things (object composition and inheritance), before looking too much further at different ways of doing them.
Because ultimately, it doesn't make any difference to the finished code, if you used a factory, or if you used a function which modified a generic object, or if you just used a whole lot of classes in the middle of your code... The program will run great, or will die, any way you slice it.
Where it does make a difference is in how you organize your code, and how you compose your code.
You don't really need a factory if all you're doing is making a button on the page.
If you're making a full-featured MP3 player on your page, which needs 6 buttons, a play-list, a progress-bar and a display for track name, artist name and cover art...
...NOW is a great time to start looking into factory patterns for figuring out how to put those pieces together, to ask for one thing, and have it spit out the finished product, off the assembly line.
I think from your perspective there isn't much of a difference, but if you go one step further and implement the abstract factory pattern, or you start to polymorph your factories, you can save a lot of work every time you write a new one.
In javascript, since you can set any value to an object because the language doesnt have private values, factories can be verry powerfull and inherit most of its logic from base-classes if you work with a framework that supports OOP standarts for objects.
EDIT
Ok, one thing, in my eyes one of the most important when it comes to JavaScript and those patterns, is prototyping.
prototyping is basicly the way you define objects in javascript so the runtime actually recognizes the object and can tell it apart from other objects.
basicly only using prototypes looks like this:
var Person = function(name){
this.name = name
}; //constructor
Person.prototype.constructor = Person;
Person.prototype.name = 'Dave';
Person.prototype.getName = function() {
return this.name;
}
some test code:
var dave = new Person('Dave');
console.log(dave.getName());
and finally a factory:
var PersonFactory = function(name) {
return new Person(name);
}
Now the problem with that anotation usually is that it is poorly maintainable and it features no inheritance.
Now comes what most frameworks to:
You can create helper functions building up your prototypes and even build a prototype chain. basicly you define an object that takes in another object and it resolves the other objects members into the prototypes of the desired class object, leaving open all sorts of possibilitys for inheritance etc.
some examples can be found here:
http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures
i like the way mootools handles classes:
var MyClass = new Class({
Extends: MyOtherClass
Implements: [MyInterface, MyOtherInterface],
myPublicValue: null,
myOtherValue: null,
initialize: function() {
//constructor
},
doStuff: function() {
return 'stuff done';
}
});
Drawbacks of the mootools class system itself:
-Closure Compiler doesnt like trailing commas, you tend to leave them in your code
-Allmost no IDE supports autocompletion for mootools classes (because the prototypes arent
annotated in a file, could be resolved using scripts to resolve your classes into prototyped files)
Now with this there are tons of design desicions you could go for, let your factories inherit from your own prototype helper class, using the prototype helper class to create the actual factory (some recursion in here), you could resolve each object on its creation (lazy loading like) or resolve every class object on page load (be carefull, if you go into inheritance, in most implementations of it classes you derive from must be resolved first)
or go any way possible.
i hope that helped out :)
(and sorry for my bad english right now, im pretty tired tonight xD)
Related
var nextid = 0
function Animal(name) {
this.name = name
Object.defineProperty(this, 'nextid',
{value: nextid++, writable: false})
}
var animal1 = new Animal('dog')
var animal2 = new Animal('cat')
I wonder if this is a good way compared to using a closure or a factory pattern?
My question is similar to this thread(closure and factory pattern suggested):
Incrementing object id automatically JS constructor (static method and variable)
Ids shouldn't be generated as part of constructing an object: they should be assigned to the object.
Think of an athletic race: do runners choose their dorsal?
function Animal() {
}
var idGenerator = new IdGenerator();
var animal = new Animal();
animal.id = idGenerator.generate();
Probably you might still be able to generate ids in a constructor, but I would try to avoid hard-coding id generation injecting an idGenerator instead:
function Animal(idGenerator) {
this.id = idGenerator.generate();
}
BTW my two cents is you should go with the first approach: runners don't assign dorsals themselves.
Those closures and factory patterns in the linked answer exist solely to encapsulate the nextid variable in a local scope or factory instance. How you create the animal - as a plain object, as a class instance, or an instance with a readonly property - has nothing to do with this. Each of them are equally good.
Whether you actually need the encapsulation depends on your modularisation approach (e.g. the closure is pointless in a node module) and the uniqueness requirements for ids.
I am learning JS these days and I am unable to assimilate this Functional Pattern on page 52 of the book.
Functional
One weakness of the inheritance patterns we have seen so far is that we get no privacy.
All properties of an object are visible. We get no private variables and no
private methods. Sometimes that doesn’t matter, but sometimes it matters a lot. In frustration, some uninformed programmers have adopted a pattern of pretend
privacy. If they have a property that they wish to make private, they give it an odd looking name, with the hope that other users of the code will pretend that they cannot
see the odd looking members. Fortunately, we have a much better alternative in
an application of the module pattern.
We start by making a function that will produce objects. We will give it a name that
starts with a lowercase letter because it will not require the use of the new prefix. The
function contains four steps:
It creates a new object. There are lots of ways to make an object. It can make an
object literal, or it can call a constructor function with the new prefix, or it can
use the Object.beget method to make a new instance from an existing object, or
it can call any function that returns an object.
It optionally defines private instance variables and methods. These are just ordinary
vars of the function.
It augments that new object with methods. Those methods will have privileged
access to the parameters and the vars defined in the second step.
It returns that new object.
Here is a pseudocode template for a functional constructor (boldface text added for
emphasis):
var constructor = function (spec, my) {
var that, //other private instance variables;
my = my || {};
// Add shared variables and functions to my
that = a new object;
// Add privileged methods to that
return that;
}
The spec object contains all of the information that the constructor needs to make an
instance. The contents of the spec could be copied into private variables or transformed
by other functions. Or the methods can access information from spec as they
need it. (A simplification is to replace spec with a single value. This is useful when
the object being constructed does not need a whole spec object.)
Can anyone explain, what's going on there (in layman terms) and where such a pattern is useful?
Note: While the book you refer to is indeed an immensely helpful book, its quite ancient. Some of the "good" (and even "bad") parts have been replaced by even better alternatives and features in newest versions of JavaScript.
One weakness of the inheritance patterns we have seen so far is that
we get no privacy. All properties of an object are visible. We get no
private variables and no private methods.
A Javascript object has "properties", which can be other objects, or functions. Consider:
var obj = {a: 1, do: function(){console.log('done');} }
Nothing is stopping you from calling obj.a = 5, or obj.done().
But one might counter that that's not a good way of creating objects. We better have a prototype or class from which we can create new instances:
function Animal(name) {
this._name = name;
}
Animal.prototype.print = function(){console.log(this._name)};
or in more recent JavaScript versions:
class Animal {
constructor(name){
this._name = name;
}
print(){
console.log(this._name);
}
}
In frustration, some uninformed programmers have adopted a pattern of
pretend privacy. If they have a property that they wish to make
private, they give it an odd looking name, with the hope that other
users of the code will pretend that they cannot see the odd looking
members.
This is a comment on above code. When declaring JavaScript classes or functions, there is no official, standard, "fool proof AND syntactically elegant" way of keeping instance variables private. That is, an easy, clean way of declaring a variable that is only accessible to methods defined in that class or prototype (See this answer). So, people follow some agreed upon patterns, one of which is prefixing the variables names with a _. This actually provides no privacy to internal variables of a class instance.
With advent of the module system, one could write JavaScript code in a separate file/container and choose to make only specific objects visible to the outside world. A CommonJS example:
Animal.js:
const props = new WeakMap();
class Animal {
constructor(name){
props.set(this,{});
props.get(this).name = name;
}
set age(n){
props.get(this).age = age;
}
function print(){
console.log(props.get(this));
}
}
module.exports = Animal;
Above is one of the ways to declare a class with private properties not accessible from outside unless intentionally leaked. Notice how the object props is not exported to outside world.
Fortunately, we have a much better alternative in an application of
the module pattern.
You might think that the above module code is actually what this text means, but the above implementation is a newer version using latest features. The old school way the points in text illustrate is to expose an object creator (a.k.a factory) function. Everything declared inside the creator function and outside the created object is private by design:
function createAnimal(name){
var age = 0;
var animal = {};
animal.setAge = function(a){age = a;};
animal.getName = function(){return name;};
animal.print = function(){console.log({'name':name,'age':age});};
}
Inheritance here is a call to super creator and modifying the super instance:
function createDog(name, color){
var breed = 'unknown';
var dog = createAnimal(name);
dog.setBreed = function(b){breed = b;};
}
Essentially, the idea is to hide private variables within a closure. The variables being closed over are the (not shown) "other private instance variables", and the methods that actually are closing over these variables are the (also not shown) "privileged methods".
For example, take this function:
var createBoard = function (rows, cols) {
var cells = [];
var board = {};
for (var i = 0; i < rows; i++) {
cells[i] = [];
for (var j = 0; j < cols; j++) {
cells[i][j] = { player: null };
}
}
board.play = function (row, col, player) {
if (cells[row][col].player === null) {
cells[row][col].player = player;
}
};
board.getPlayer = function (row, col) {
return cells[row][col].player;
};
return board;
};
And let's assume we call this function to create an 8x8 gameboard:
var board = createBoard(8,8);
board.play(1,2,"Player1");
console.log(board.getPlayer(1,2));
board.play(1,2,"Player2"); // Doesn't actually do anything
// Note this code has no direct access to cells[][] except via the two
// methods we defined on the board object.
In this case, we return a board object. The board internally has access to a cells array, but we don't let anyone modify this except using our two methods, play (which occupies a board space only if it was previously unoccupied) and a getPlayer method that returns the player at a given space. Cells[][] is totally hidden to the user of this code - they couldn't cheat by changing our cell array directly.
JavaScript is an object-based language based on prototypes, rather than being class-based. 1
Compare that with Object-Oriented languages based on classes like PHP, Java, etc. In those languages, a class can be defined and member variables can have various visibility inside and outside the class. For instance, PHP has visibility set on three levels: public, protected or private.
Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited classes. Members declared as private may only be accessed by the class that defines the member.2
class MyClass {
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello() {
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
But in JavaScript, we don't really have such a concept of private variables (in the same sense). That is what the author is talking about when describing the module pattern.
So if we wanted to make an analagous construct in Javascript, we could make something like this:
var MyClass = function (rows, cols) {
//this could be used in prototype functions
var private = 'Private';
var members = {
public: 'Public';
getHello: function() {
return 'MyClass _ ' + private;
}
};
return members;
};
I learned javascript inheritance via the old school constructor function / new keyword method, like this:
function People(name, age){
this.name = name;
this.age = age;
this.yearsUntilRetire = yearsLeft;
}
function yearsLeft(){
var numYears = 65 - this.age;
return numYears;
}
lady = new People("Lady Gaga", 28);
mickey = new People("Mickey Mouse", 99);
Now, when using this method I can create new instances of the constructor function "People" and pass in data that will fill out the values of the function (in this case, that's "name" and "age"). I'm just now learning prototypal inheritance and I get that objects inherit from other objects directly and that javascript is a classless language, for example, I know how to do the following, which I learned from a more updated tutorial:
var person = {
kind: 'person'
}
var zack = Object.create(person);
zack.kind = 'zack'
console.log(zack.kind); //=> 'zack'
// zack now has a 'kind' property
console.log(person.kind); //=> 'person'
// person has not being modified
But my question is that there doesn't appear to be any method of "passing" arguments into the constructor function to make the values of the new object more dynamic and to fill in the blueprint like is the case with constructor functions ("name" and "age") and instead it appears as though in cases where I wanted to just change the values I would just OVERWRITE the original data for some new object, like above:
zack.kind = 'zack'
At this part of the code it seems that I just stamped directly over zack.kind, which would have ended up having the value of 'person'.
Is the manipulation of values in prototypal inheritance normally done like this? Where you just stamp over the data? Or is there some method of keeping the blueprint form of a value and only passing in some select pieces of data like with constructor functions arguments? It seems strange that I don't pass data into the function but just stamp over the other objects data that you want to change (I know it doesn't change the original objects values, but it does feel a little bit loose and strange). It seems odd to me since I've been using constructor functions for a few months and want to make sure I am working the correct way. Sorry if this is a newbie question.
There is a common convention to have a factory function that is used instead of a constructor. This method encapsulates object creation and is allowed to have parameters.
In this simple example it could be:
var person = {
kind: 'person',
create: function(kind) {
var p = Object.create(person);
p.kind = kind;
return p;
}
}
var zack = person.create('zack');
If you want to add properties to the new object you are creating using Object.create you can use the second argument like this:
var zack = Object.create(person, { kind: {
value: 42,
writable: true,
configurable: true }
});
But you can also just use a function and new, there is no difference in this case. You can see where using Object.create might be beneficial here. The only thing it really gives you, in my opinion, is being to define properties such as writable, enumerable, etc. as defined here.
I'm just getting into JavaScript and I'm trying to wrap my head around prototypal inheritance. It appears that there's multiple ways to achieve the same effect, so I wanted to see if there is any best practices or reasons to do things one way over the other. Here's what I'm talking about:
// Method 1
function Rabbit() {
this.name = "Hoppy";
this.hop = function() {
console.log("I am hopping!");
}
}
// Method 2
function Rabbit() {}
Rabbit.prototype = {
name: "Hoppy",
hop: function() {
console.log("I am hopping!");
}
}
// Method 3
function Rabbit() {
this.name = "Hoppy";
}
Rabbit.prototype.hop = function() {
console.log("I am hopping!");
}
// Testing code (each method tested with others commented out)
var rabbit = new Rabbit();
console.log("rabbit.name = " + rabbit.name);
rabbit.hop();
All of these appear to have the same effect individually (unless I'm missing something). So is one method preferred over the other? How do you do it?
When you put a method on the prototype, every instance object shares the same reference to the method. If you have 10 instances, there is 1 copy of the method.
When you do what you did in example 1, every instance object has its own version of the same method, so if you create 10 of your objects, there are 10 copies of the code running around.
Using the prototype works because javascript has machinery for associated a function execution with a instance, i.e. it sets the this property for the execution of the function.
So using the prototype is highly preferred since it uses less space (unless of course, that is what you want).
In method 2, you are setting the prototype by setting it equal to an object literal. Note that here you are setting a property, which I think you don't intend to do, since all instances will get the same property.
In Method 3, you are building the prototype one assignment at a time.
I prefer method 3 for all things. i.e. In my constructor I set my property values
myObj = function(p1){
this.p1; // every instance will probably have its own value anyway.
}
myObj.prototype.method1 = function(){..} // all instances share the same method, but when invoked **this** has the right scope.
Let's look at your examples one at a time. First:
function Rabbit() {
this.name = "Hoppy";
this.hop = function() { //Every instance gets a copy of this method...
console.log("I am hopping!");
}
}
var rabbit = new Rabbit();
The above code will work, as you have said in your question. It will create a new instance of the Rabbit class. Every time you create an instance, a copy of the hop method will be stored in memory for that instance.
The second example looked like this:
function Rabbit() {}
Rabbit.prototype = {
name: "Hoppy",
hop: function() { //Now every instance shares this method :)
console.log("I am hopping!");
}
}
var rabbit = new Rabbit();
This time, every instance of Rabbit will share a copy of the hop method. That's much better as it uses less memory. However, every Rabbit will have the same name (assuming you don't shadow the name property in the constructor). This is because the method is inherited from the prototype. In JavaScript, when you try to access a property of an object, that property will first be searched for on the object itself. If it's not found there, we look at the prototype (and so on, up the prototype chain until we reach an object whose prototype property is null).
Your third example is pretty much the way I would do it. Methods shared between instances should be declared on the prototype. Properties like name, which you may well want to set in the constructor, can be declared on a per-instance basis:
function Rabbit(rabbitName) {
this.name = rabbitName;
}
Rabbit.prototype.hop = function() {
console.log("Hopping!");
}
This is an important issue that is often misunderstood. It depends what you're trying to do. Generally speaking, hvgotcode's answer is right on. Any object that will be instantiated frequently should attach methods and properties to the prototype.
But there are advantages to the others in very specific situations. Read this, including the comments: http://net.tutsplus.com/tutorials/javascript-ajax/stop-nesting-functions-but-not-all-of-them/
There are occasions when method 1 above helps, enabling you to have "private" readable/writable properties and methods. While this often isn't worth the sacrifice in heavily instantiated objects, for objects instantiated only once or a few times, or without many internal assignments, or if you're in a dev team environment with lots of different skill levels and sensibilities, it can be helpful.
Some devs incorporate another good strategy that attempts to bridge some of the shortcomings of the others. That is:
var Obj = function() {
var private_read_only = 'value';
return {
method1: function() {},
method2: function() {}
};
};
// option 4
var Rabbit {
constructor: function () {
this.name = "Hoppy";
return this;
},
hop: function() {
console.log("I am hopping!");
}
};
var rabbit = Object.create(Rabbit).constructor();
console.log("rabbit.name = " + rabbit.name);
rabbit.hop();
When doing prototypical OO using new and constructor functions is completely optional.
As has already been noted, if you can share something through the prototype do so. Prototypes are more efficient memory wise and they are cheaper in terms of instantiation time.
However a perfectly valid alternative would be
function Rabbit() {
// for some value of extend https://gist.github.com/1441105
var r = extend({}, Rabbit);
r.name = "Hoppy";
return r;
}
Here your extending "instances" with the properties of the "prototype". The only advantage real prototypical OO has is that it's a live link, meaning that changes to the prototype reflect to all instances.
Do some performance testing (declare around 1 milion rabbit variables) . First method will be the most time and memory consuming.
I have only recently started programming significantly, and being completely self-taught, I unfortunately don't have the benefits of a detailed Computer science course. I've been reading a lot about JavaScript lately, and I'm trying to find the benefit in classes over the prototype nature of JavaScript. The question seems to be drawn down the middle of which one is better, and I want to see the classical side of it.
When I look at the prototype example:
var inst_a = {
"X": 123,
"Y": 321,
add: function () {
return this.X+this.Y;
}
};
document.write(inst_a.add());
And then the classical version
function A(x,y){
this.X = x;
this.Y = y;
this.add = function(){
return this.X+this.Y;
};
};
var inst_a = new A(123,321);
document.write(inst_a.add());
I begun thinking about this because I'm looking at the new ecmascript revision 5 and a lot of people seem up in arms that they didn't add a Class system.
Inheritance is not really possible without using the psuedoclassical style. See what Douglas Crockford has to say about it. Even if you were to use a purely prototypal object structure, you'd have to create a constructor function for inheritance (which Crockford does, then abstracts it behind a create method then calls it purely prototypal)
When you create an object via new, it will use it's prototype chain to look for properties not found in the instance.
So, for example, you could add the add method to A.prototype just once, instead of redefining a new copy of the same function every time you create a new instance of A.
function A(x,y){
this.X = x;
this.Y = y;
};
//define add once, instead of every time we create a new 'A'
A.prototype.add = function(){
return this.X+this.Y;
};
With the second method you can create instances of A, allowing you to have multiple at a time. For example:
var inst_one = new A(123,321);
var inst_two = new A(456,654);
// some meaningful code here...
document.write(inst_one.add());
// some more meaningful code here...
document.write(inst_two.add());
The example you provided is trivial, so let's make up a more intuitive example:
function Comment(user,text){
this.user = user;
this.text = text;
this.toString = function(){
return '<span class="comment">'+this.text+' - <a class="user">'+this.user+'</a></span>';
};
};
var comments = someFunctionThatReturnsALotOfCommentObjects();
for(c=0;c<comments.length;c++)
document.getElementById('comments_container').innerHTML += comments[c].toString();
This (hopefully) demonstrates the benefit of being able to create multiple instances of a class. This is not a fundamental JavaScript concept, it's a fundamental Object Oriented Programming concept, which may be why you are unfamiliar with it if you haven't had formal programming courses.
To be fair JavaScript does have classes. Well, maybe some would argue with that, but I consider it just semantic splitting of hairs. If a class is taken to be a blue print for creating objects than a JavaScript function can serve in that capacity. There's not much difference in function here, only form:
class someObj
{
private int x;
public int returnX()
{
return x;
}
}
someObj temp = new someObj();
-
function someObj {
var x;
this.returnX = function() {
return x;
};
}
var temp = new someObj();
Under the hood they're different, but you can use either form to serve the same end.
Prototypical really differs in inheritance. In prototypical inheritance when you create a new object you're really copying an instance of the prototype object and then adding new fields or members to it. Classical inheritance, on the other hand, isn't dealing with an instance but just a "blue print". For instance, in JavaScript you'd say:
temp.prototype = new someOtherObj(); //Creating a new instance to serve as the prototype.
In a classical language you might say:
class someObj : someOtherObj //Copying the "blue print" over.
The implication is that data will be shared among derived objects in the prototype language. I once wrote a function and had another function derive from it through prototyping in JavaScript. This base object held a reference to a DOM object and when I would change it in one child object it would change it for all instances of that child object. This is because, again, in the prototype language you're deriving from an instance and not a "blue print".
The classical version allows you to declare private variables scoped "inside" the object, whilst the prototype version does not.