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.
Related
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.
All, I found there are 3 ways to declare object in javascript.
var Waffle = {
tastes:'yummy'
};
var Waffle = function()
{
this.tastes='yummy';
};
function Waffle() {
var that = {};
that.tastes = "yummy";
return that;
}
The first way is Object literal it doesn't have a constructor.
I think the equal way to Object literal is below.
var Waffle = new Object();
Waffle.tastes = 'yummy';
(If my understanding is wrong. Please correct me.)
I want to know what the difference of these 3 ways is.
Which one is the best choice?
Thanks.
The literal notation and new Object() creates an object whose prototype is directly the Object. Also, properties and methods are attached on the instance.
/*
Object
A
| instance.__proto__
|
instance
*/
//all 3 yield the same result
var foo1 = {
bar : 'bam!'
}
var foo2 = {}
foo2.bar = 'bam!';
var foo3 = new Object();
foo3.bar = 'bam!';
The constructor approach, either the declared function or the assigned function expression approach, has an additional prototype level between the instance and the Object, which contains your prototype functions attached to the constructor's prototype. Anything attached to the constructor's prototype are shared across all instances.
/*
Object
A
| instance.__proto__.__proto__
|
constructor.prototype
A
| instance.__proto__
|
instance
*/
//these 2 are the same
//bar is attached at the instance
//function expression assigned to variable foo1
var foo1 = function(){
this.bar = 'bam!'
}
//function declaration named foo2
function foo2(){
this.bar = 'bam!'
}
//==========================================================================//
//these 2 are the same, but not the same as above
//methods live on the prototype level and are shared across instances
//function expression assigned to variable foo1
var foo1 = function(){}
//function declaration named foo2
function foo2(){}
foo1.prototype.bar = 'bam!'
foo2.prototype.bar = 'bam!'
The third approach returns a new literal. You don't get the benefits of the constructor method and prototype sharing. It's as if you just called Waffle like an ordinary function, created a literal, attached properties and methods, and returned it.
Best Choice: Depends on purpose.
Object literals:
Shorter than new Object and can attach methods/properties upon definition.
Properties/methods live on the instance, no running up the prototype chain which means faster look-up.
Unoptimized creation of objects might lead to duplicates, which waste memory. For example, creating functions per instance instead of sharing via the prototype.
Constructor:
Classical OOP style
Inheritance
Shared methods via the prototype means less memory used, as opposed to per instance methods.
Forgetting the new might have unwanted consequences, like attaching globals (if window is the context)
You can check these out in the Chrome Developer tools. Create them in the Console, and watch these expressions in the Sources tab
The first is an object literal and is the same as:
var Waffle = new Object();
Waffle.tastes = 'yummy';
which is the same as:
var Waffle = {};
Waffle.tastes = 'yummy';
but of course, their instantiations take multiple lines.
Your second and third examples are functions. Your second example is an expression, while your third example is a declaration. Here's an explanation of their differences: What is the difference between a function expression vs declaration in JavaScript?
Be careful with your second example (the expression), because in order to modify this (correctly), you need to use var waffle = new Waffle();. Since this is an expression, alternatively you could've used a declaration like:
function Waffle() {
this.tastes='yummy';
}
(to understand the main difference between that and the original, which I don't think affect many people ever, read the link I provided)
The third example is a basic function that returns a new object literal.
As for the best choice...I don't think there's a concrete, definite answer.
Your first example creates a simple, single object. You can add/change properties and methods on it. But it inherits directly from Object. I like to use this when I need one big object for holding many things, and its structure is static. To reuse this, your third example is needed.
Your second example is convenient because you can invoke a new instance, giving the effect of classic OOP...and is the one I normally use. Although the caveat is that you have to use new, otherwise the value of this will be window, which is bad. At the same time, you can modify this prototype and all instances will share it. It also gives you flexibility of having "private" variables, such as:
function Waffle() {
var testing = 0;
this.name = "A";
this.myMethod = function () {
return testing;
};
}
Your third example is similar to the second, except that you can't tap into a prototype, since you're returning an Object. It's basically using your first example, but making it reusable. It also allows for "private" variables like above, as well.
So if you're looking for a single object, use your first example. If you're looking for reusability, I'd suggest your second example, while the third is still an example. Hopefully I explained enough about each for you to determine which suits your needs.
All, I found there are 3 ways to declare object in javascript.
var Waffle = {
tastes:'yummy'
};
var Waffle = function()
{
this.tastes='yummy';
};
function Waffle() {
var that = {};
that.tastes = "yummy";
return that;
}
The first way is Object literal it doesn't have a constructor.
I think the equal way to Object literal is below.
var Waffle = new Object();
Waffle.tastes = 'yummy';
(If my understanding is wrong. Please correct me.)
I want to know what the difference of these 3 ways is.
Which one is the best choice?
Thanks.
The literal notation and new Object() creates an object whose prototype is directly the Object. Also, properties and methods are attached on the instance.
/*
Object
A
| instance.__proto__
|
instance
*/
//all 3 yield the same result
var foo1 = {
bar : 'bam!'
}
var foo2 = {}
foo2.bar = 'bam!';
var foo3 = new Object();
foo3.bar = 'bam!';
The constructor approach, either the declared function or the assigned function expression approach, has an additional prototype level between the instance and the Object, which contains your prototype functions attached to the constructor's prototype. Anything attached to the constructor's prototype are shared across all instances.
/*
Object
A
| instance.__proto__.__proto__
|
constructor.prototype
A
| instance.__proto__
|
instance
*/
//these 2 are the same
//bar is attached at the instance
//function expression assigned to variable foo1
var foo1 = function(){
this.bar = 'bam!'
}
//function declaration named foo2
function foo2(){
this.bar = 'bam!'
}
//==========================================================================//
//these 2 are the same, but not the same as above
//methods live on the prototype level and are shared across instances
//function expression assigned to variable foo1
var foo1 = function(){}
//function declaration named foo2
function foo2(){}
foo1.prototype.bar = 'bam!'
foo2.prototype.bar = 'bam!'
The third approach returns a new literal. You don't get the benefits of the constructor method and prototype sharing. It's as if you just called Waffle like an ordinary function, created a literal, attached properties and methods, and returned it.
Best Choice: Depends on purpose.
Object literals:
Shorter than new Object and can attach methods/properties upon definition.
Properties/methods live on the instance, no running up the prototype chain which means faster look-up.
Unoptimized creation of objects might lead to duplicates, which waste memory. For example, creating functions per instance instead of sharing via the prototype.
Constructor:
Classical OOP style
Inheritance
Shared methods via the prototype means less memory used, as opposed to per instance methods.
Forgetting the new might have unwanted consequences, like attaching globals (if window is the context)
You can check these out in the Chrome Developer tools. Create them in the Console, and watch these expressions in the Sources tab
The first is an object literal and is the same as:
var Waffle = new Object();
Waffle.tastes = 'yummy';
which is the same as:
var Waffle = {};
Waffle.tastes = 'yummy';
but of course, their instantiations take multiple lines.
Your second and third examples are functions. Your second example is an expression, while your third example is a declaration. Here's an explanation of their differences: What is the difference between a function expression vs declaration in JavaScript?
Be careful with your second example (the expression), because in order to modify this (correctly), you need to use var waffle = new Waffle();. Since this is an expression, alternatively you could've used a declaration like:
function Waffle() {
this.tastes='yummy';
}
(to understand the main difference between that and the original, which I don't think affect many people ever, read the link I provided)
The third example is a basic function that returns a new object literal.
As for the best choice...I don't think there's a concrete, definite answer.
Your first example creates a simple, single object. You can add/change properties and methods on it. But it inherits directly from Object. I like to use this when I need one big object for holding many things, and its structure is static. To reuse this, your third example is needed.
Your second example is convenient because you can invoke a new instance, giving the effect of classic OOP...and is the one I normally use. Although the caveat is that you have to use new, otherwise the value of this will be window, which is bad. At the same time, you can modify this prototype and all instances will share it. It also gives you flexibility of having "private" variables, such as:
function Waffle() {
var testing = 0;
this.name = "A";
this.myMethod = function () {
return testing;
};
}
Your third example is similar to the second, except that you can't tap into a prototype, since you're returning an Object. It's basically using your first example, but making it reusable. It also allows for "private" variables like above, as well.
So if you're looking for a single object, use your first example. If you're looking for reusability, I'd suggest your second example, while the third is still an example. Hopefully I explained enough about each for you to determine which suits your needs.
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)