Difference In declaring Javascript objects - javascript

I have been reading a few different Javascript authors and each has their preferred way to declare properties on objects. None of the authors really explains the difference between these different ways. What are the differences and which way is the preferred declaration to us?
var One = function() {
var self = this;
self.foo = function() {};
return self;
}
var two = function() {
foo: function() {}
};
var three = function() {
var _foo = function() {};
three.foo = _foo;
}

tl;dr - See conclusion
Introduction
Declaring objects in javascript can be done many different ways, and from my point of view it all depends on how complex your project is.
The examples you proposed would be ways to declare variables within a complex project. You could even say for project maintainability and code quality the examples you proposed can be very interesting.
Part 1 - First example
Your first example you proposed was this function.
var One = function(){
var self = this;
self.foo = function(){};
return self;
}
Context: Global -> One()
Suppose we don't create an instance of One (not using new) This function has two objectives.
Attach the foo function to its parents context (usually window object = globally)
Return foo function
You could say you're killing two birds with one stone. While doing two things at once can be interesting, in the end it could really become a context problem.
Context is pretty much asking yourself, what does this refer to? Non instantiated functions inherit the parents context which is fine if none of those parents are instantiated themselves. If this is the case (meaning this != window object) and your primary goal was to attach foo globally well it just won't work.
Context: Self -> new One()
If you call this function with new, this will be different. this will refer to an instance of One. This is a lot more logical way.
In the end you could say that an instance of One will feel almost like an object.
Comparing with objects
I say almost mainly because what is the difference if One was:
var One_object = {
foo: function(){}
}
Well there isn't really, except you'll be more flexible with an object rather than an instance of a function.
//This will not work.
var a = new One();
a.titi = function(){
alert('titi');
}
//This will work
One_object.titi = function(){
alert('titi');
}
Improving the example
The only way that One as an instance can become interesting is if you declare multiple instances. Performance wise and memory wise it'll be more interesting.
var One = function(foo){
//auto instantiate it's self
if(!(this instanceof One)){
return new One(foo);
}
this.foo = foo || function(){};
}
Creating multiple instances of One with the same function probably defeats the purpose, so here is an example of how you could improve One.
var a = One(function(){
alert('instance one');
});
var b = One(function(){
alert('instance two');
});
Part 2 - Second example
var two = function() {
foo: function() {}l
};
Is actually wrong as I'm sure you've noticed from the comments. It should be instead:
var two = {
foo: function() {}
};
Where two is in fact an object and not a function.
This way of declaring variables/functions ensures that you are not overriding on a global scope any other function named "foo".
This can be very useful when you have a lot of js and you are declaring a lot of variables.
In this case, to access foo you need to simply call two.foo();
This is honestly my preferred way of declaring variables.
Variables are not scattered all across the js file.
They do not override any existing variables with the same name
It's clean and maintainable.
They can easily be moved around.
With this in mind, here is an example:
var options = {
foo: function(){
console.log('This is foo');
},
toto: function(){
console.log('This is titi');
}
};
var example = function(options){
options.foo();
options.toto();
}
example(options);
Part 3 - Barbaric
var three = function() {
var _foo = function() {};
three.foo = _foo;
}
A good standard when writing code is to keep the code readable. While this may work, it's not good practice. The main issue with writing Javascript is that it can easily become unreadable.. And in this case it feels barbaric (personal opinion).
Conclusion
As you've probably noticed example two is my preferred way (and to many others I know) in declaring Objects for the following reasons:
Structured
Organized
Easy to handle
Easy to maintain
Flexibility
No conflicts
Feel free to point out on anything I've missed.

In JavaScript you can declare "Objects" via several ways. The most easy way is:
var myObject = {}
from here on, adding methods or attributes is very easy as well:
myObject.myFirstMethod = function(){};
myObject.myFirstAttr = true;
myObject.mySecondAttr = "hello world!";
in this case, you would add those functions and attributes to your "myObject" Object. But there is a better and much cleaner way to do such stuff:
var myObject = function();
myObject.prototype.method1 = function(){};
myObject.prototype.method2 = functiion(){};
myObject.prototype.attr1 = true;
myObject.prototype.attr2 = "hello world!";
myObject.prototype.setAttr1 = function(value){
this.attr1 = value;
}
myObject.prototype.setAttr2 = function(value){
this.attr2 = value;
}
if you declared your Object this way, you can use
var myObjectInstance = new myObject();
this Object now has got every methods and attributes which you had defined in your prototype. more about prototypes:
http://www.w3schools.com/js/js_object_prototypes.asp
edit:
note that "this" in JavaScript means the "element", what called the actual method and NOT the object itself in any case...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

Related

Performance issue when assigning the same function to multiple variables in JavaScript

[Edited] Important! Function is treated as object, not value. So this question is invalid because it is based on a wrong assumption. This edit serves as a note to avoid confusing anyone who read this question.
Let's say I have a function expression of foo
var foo = function() {
return this.member;
}
and I have the following class and instantiate many objects of it with "foo" as the callback function.
var simpleClass = function(callback) {
this.member = "I am an instance variable";
this.callback = callback;
}
var a = new simpleClass(foo);
var b = new simpleClass(foo);
var c = new simpleClass(foo);
.
.
.
Since in JavaScript arguments are passed by value, we are copying the value([Edited]actually it should be object) of foo to a, b, c and other variables' callback. If my understanding is correct, then foo will be copied n times, each occupying certain memory space for each object.
Base on this understanding, I have some performance questions regarding this situation:
Does copying functions to multiple variables harm the performance?
Since each copies of "foo" as simpleClass object's "callback" occupies space, if there are really many simpleClass object(e.g. in a DOM library I have thousands of DOM objects which has the same function css()), will it harm the performance significantly? Or most JavaScript engine has mechanism to tackle this situation and it generally won't harm at all?
In situation where potentially hundreds or thousands of object will be created. Is it always a good practice to put those shared functions to the prototype of an object?
Since all the object instance share the same class prototype, if we put the "foo" function to the prototype of simpleClass, then there should have only one copy of the "foo" and every object instance will just execute the prototype copy of "foo" when needed. Is this a good practice we should follow?
I try to search for similar keywords but couldn't find the right wordings to find the solution to this problem. Please correct my wordings if I make anything unclear. And of course if I have any misunderstandings please correct me too. I appreciate everyone's help.
I don't understand this well enough to give you an authoritative answer but I can say this:
then foo will be copied n times, each occupying certain memory space for each object.
This is incorrect. foo is a variable pointing to a function. foo is not the function, if you did var bar = foo, bar now also points to the function, the same function. So the function is not copied. A reference to the function is assigned to this.callback.
In situation where potentially hundreds or thousands of object will be created. Is it always a good practice to put those shared functions to the prototype of an object?
What is and isn't good practise in JavaScript is up for debate. Some people like to use class/prototype, other people use object literals. It's definitly true though that prototype can help reduce the memory footprint of your application. See it like this: if you're using prototype you're giving the JavaScript engine more information about the object, ie. that your object is similar to all these other objects. The JavaScript engine should be able to make optimizations based on that. I can't say too much about the exact numbers, it might vary wildly per vendor.
Your code sample is equivalent to this:
function foo() {}
function myClass() {
this.foo = foo;
}
var instance = new myClass();
If you used prototypes you'd write:
function myClass() {}
myClass.prototype.foo = function () {};
var instance = new myClass();
If you used object literals you'd have:
function foo() {};
function create_myClass() {
return {
foo: foo
};
}
var instance = create_myClass();
In all the cases above the function foo is never copied. In these cases below you do create a new copy of foo every time:
function myClass() {
this.foo = function () {}; // new copy every time
}
var instance = new myClass();
function create_myClass() {
return {
foo: function () {}; // new copy every time
};
}
As for performance. This is the tip I always give: don't start optimizing until you run into a measurable problem. Always measure with real data. Additionally, if you think your way of doing things is good then it's likely that JavaScript engine vendors will optimize for that method.
In javascript reference is copied not the object itself so you can't assign the value to callback to change the function from inside constructor. You your code all those object will share the function, look at this snipet:
var foo = function() {
return this.member;
}
var simpleClass = function(callback) {
this.member = "I am an instance variable";
this.callback = callback;
}
var a = new simpleClass(foo);
var b = new simpleClass(foo);
alert(a.callback === b.callback ? 'shared' : 'not shared');

Variable privacy in Javascript's behaviour delegation pattern

Since my last question, I've been studying Javascript's prototype model and trying to get rid of the OOP vision I inherited from other languages (pun slightly intended).
I went back to basics and read Crookford's Javascript: The Good Parts, along with You Don't Know JS material and decided to stick with the so called behaviour delegation.
Restructuring my previous example implementing behaviour delegation and namespacing, I wrote:
var GAME = {};
(function(namespace) {
var Warrior = {};
Warrior.init = function(weapon) {
this.setWeapon(weapon);
};
Warrior.getWeapon = function() {
return this.weapon;
};
Warrior.setWeapon = function(value) {
this.weapon = value || "Bare hands";
};
namespace.Warrior = namespace.Warrior || Warrior;
})(GAME);
(function(namespace) {
var Archer = Object.create(namespace.Warrior);
Archer.init = function(accuracy) {
this.setWeapon("Bow");
this.setAccuracy(accuracy);
};
Archer.getAccuracy = function() {
return this.accuracy;
};
Archer.setAccuracy = function(value) {
this.accuracy = value;
};
namespace.Archer = namespace.Archer || Archer;
})(GAME);
So, everytime I copy a new Archer object:
var archer1 = Object.create(GAME.Archer);
only this object will be created, conserving memory.
But what if I don't want to expose "accuracy" attribute? The attribute would only increase by calling a "training()" method or something similar. I tried to use var accuracy inside the anonymous function, but it turns into kind of static variable, all instances of Archer would share the same value.
The question: Is there any way to set a variable as private while still keeping behaviour-delegation/prototypal pattern?
I do know of functional pattern as well, Here I succesfully achieved variable privacy, at the cost of memory. By going functional, every new "archer" instance generates a new "Warrior" and then a new "Archer". Even considering that Chrome and Firefox have different optmizations, testings on both report that the Delegation/Prototypal pattern is more efficient:
http://jsperf.com/delegation-vs-functional-pattern
If I go with the pure-object delegation pattern, should I just forget the classic encapsulation concept and accept the free changing nature of properties?
I would try to answer your question with something that is slightly different then this one that tells you how to use a library.
Different in that it will(hopefully) give you some ideas of how can we tackle the problem of private vars in OLOO ourselves. At least to some extent, with our own code, no external lib needed, which could be useful in certain scenarios.
In order for code to be cleaner I've striped your anonymous wrapper functions, since they are not related to problem in any way.
var Warrior = {};
Warrior.warInit = function (weapon){
this.setWeapon(weapon);
}
Warrior.getWeapon = function(){
return this.weapon;
}
Warrior.setWeapon = function (value){
this.weapon = value || "Bare hands";
}
var Archer = Object.create(Warrior);
Archer.archInit = function (accuracy){
this.setWeapon("Bow");
this.setAccuracy(accuracy);
}
Archer.getAccuracy = function (pocket) {
return pocket.accuracy;
}
Archer.setAccuracy = function (value, pocket){
pocket.accuracy = value;
}
function attachPocket(){
var pocket = {};
var archer = Object.create(Archer);
archer.getAccuracy = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]);
return Archer.getAccuracy.apply(this, args)
};
archer.setAccuracy = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]);
return Archer.setAccuracy.apply(this, args);
};
return archer;
}
var archer1 = attachPocket();
archer1.archInit("accuracy high");
console.log(archer1.getAccuracy()); // accuracy high
archer1.setAccuracy("accuracy medium");
console.log(archer1.getAccuracy()); // accuracy medium
Test code above here. (and open your browser console)
Usage
1 ) General practice in OLOO about naming functions on different levels of prototype chain is apposite from OOP. We want different names that are more descriptive and self documenting, which brigs code that is cleaner and more readable. More importantly, by giving different names we avoid recursion loop:
Archer.init = function(accuracy, pocket){
this.init() // here we reference Archer.init() again, indefinite recurson. Not what we want
...
}
Archer.archInit = fucntion (accuracy, pocket){ // better,
this.warInit() // no name "collisions" .
}
2 ) We've created an attachPocket() function that creates internal variable pocket. Creates new object with Object.create() and sets it's prototype to point to Archer. Pause. If you notice, functions that required a private var we have defined so that each of them take one more parameter(pocket), some use just pocket. Here is the trick.
By making wrapper functions like archer.setAccuracy(), archer.getAccuracy()
... we can create closures and call directly functions that need
private var (here pocket) and pass it to them as an argument.
Like so:
function AtachPocket(){
...
var pocket = {};
archer.setAccuracy = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]); // appending pocket to args
return Archer.setAccuracy(this, args);
};
...
}
Essencially by doing this we are bypassing what would have been a normal search for functions in prototype chain, just for functions that have need for a private var. This is what "call directly" refers to.
By setting the same name for a function in archer("instance") like it is in prototype chain (Archer) we are shadowing that function at the instance level. No danger of having indefinite loops, since we are "calling directly" like stated above. Also by having the same function name we preserve the normal, expected behaviour of having access to same function in an "instance" like it is in a prototype chain. Meaning that afther var archer = Object.create(Archer) we have access to function setAccuracy like we would if it had been normal search for function in prototype chain.
3 ) Every time attachPocket() is invoked it creates a new "instance" that has those wrapper functions that pass a pocket argument (all as an internal detail of implementation). And therefore every instance has own, unique, private variable.
You would use functions in an "instance" normally:
archer1.archInit("accuracy high"); // Passing needed arguments.
// Placed into pocked internally.
archer1.getAccuracy(); // Getting accuracy from pocket.
Scalability
Up to now all we have is function that "attaches a pocket" with hardcoded values like Archer.setAccuracy, Archer.getAccuracy. What if we would like to expand prototype chain by introducing a new object type like this var AdvancedArcher = Object.create(Archer), how the attachPocket is going to behave if we pass to it AdvancedArcher object that might not even have setAccuracy() function? Are we going to change attachPocket() each time we introduce some change in prototype chain ?
Let's try to answer those questions, by making attachPocket() more general.
First, expand prototype chain.
var AdvancedArcher = Object.create(Archer);
AdvancedArcher.advInit = function(range, accuracy){
this.archInit(accuracy);
this.setShotRange(range);
}
AdvancedArcher.setShotRange = function(val){
this.shotRange = val;
}
More generic attachPocket.
function attachPocketGen(warriorType){
var funcsForPocket = Array.prototype.slice.call(arguments,1); // Take functions that need pocket
var len = funcsForPocket.length;
var pocket = {};
var archer = Object.create(warriorType); // Linking prototype chain
for (var i = 0; i < len; i++){ // You could use ES6 "let" here instead of IIFE below, for same effect
(function(){
var func = funcsForPocket[i];
archer[func] = function(){
var args = Array.prototype.slice.call(arguments);
args = args.concat([pocket]); // appending pocket to args
return warriorType[func].apply(this, args);
}
})()
}
return archer;
}
var archer1 = attachPocketGen(Archer,"getAccuracy","setAccuracy");
archer1.advInit("11","accuracy high");
console.log(archer1.getAccuracy()); // "accuracy high";
archer1.setAccuracy("accuracy medium");
console.log(archer1.getAccuracy());
Test the code here.
In this more generic attachPocketGen as first argument we have a warriorType variable that represents any object in our prototype chain. Arguments that may fallow are ones that represent names of functions that need a private var.
attachPocketGen takes those function names and makes wrapper functions with same names in archer "instance". Shadowing, just like before.
Another thing to recognise is that this model of making wrapper functions and using apply() function to pass variables from closures is going to work for functions that use just pocket, functions that use pocket and other variables, and when ,of course, those variables use the relative this reference in front of them.
So we have achieved somewhat more usable attachPocket, but that are still things that should be noticed.
1) By having to pass names of functions that need private var, that usage implies that we(attachPocketGen users) need to know whole prototype chain (so we could see what functions need private var). Therefore if you are to make a prototype chain like the one here and just pass the attachPocketGen as an API to the programmer that wants to use your behaviour-delegation-with-private-variables, he/she would had to analyse objects in prototype chain. Sometimes that is not what wee want.
1a) But we could instead, when defining our functions in prototype chain (like Archer.getAccuracy) to add one property to them like a flag that can tell if that function have need for a private var:
Archer.getAccuracy.flg = true;
And then we could add additional logic that checks all functions in prototype chain that have this flg and fills the funcsForPocket.
Result would be to have just this call:
var archer1 = attachPocketGen(AdvancedArcher)
No other arguments except warriorType. No need for user of this function to have to know how prototype chain looks like, that is what functions have need for a private var.
Improved style
If we are to look at this code:
Archer.archInit = function (accuracy){
this.setWeapon("Bow");
this.setAccuracy(accuracy);
}
We see that it uses "pocket" function setAccuracy. But we are not adding pocket here as last argument to it because setAccuracy that gets called is shadowed version, the one from instance. Becouse it will be called only from an instance like so archer1.archInit(...) That one is already adding a pocket as last argument so there is on need to. That's kinda nice, but the definition of it is:
Archer.setAccuracy = function (value, pocket){ ...
and that can be confusing when making objects in prototype chain like Archer.archInit above. If we look the definition of setAccuracy it looks like we should it. So in order not have to remember that we don't have to add pocket as last arg in functions (like archInit) that use other pocket functions, maybe we should to something like this:
Archer.setAccuracy = function (value){
var pocket = arguments[arguments.length -1];
pocket.accuracy = value;
}
Test the code here.
No pocket as last argument in function definition. Now it's clear that function doesn't have to be called with pocket as an argument wherever in code.
1 ) There are other arguably minor stuff to refer to when we think about more general prototype chain and attachPocketGen.Like making functions that use pocket callable when we dont wan't to pass them a pocket, that is to toggle pocket usage to a function, but in order not to make this post too long, let's pause it.
Hope this can give you view ideas for solution to your question.

Simple javascript inheritance using $.extend and module pattern

I have wondered for a couple years now what people think of doing inheritance with a module-pattern-esque constructor pattern and WITHOUT normal prototypal inheritance. Why do programmers not use a module pattern for non-singleton js classes? For me the advantages are:
Very clear public and private scope (easy to understand the code and the api)
No needing to track the 'this' pointer via $.proxy(fn, this) in callbacks
No more var that = this, etc. with event handlers, etc. Whenever I see a 'this', I know it is context that is being passed into a callback, it is NOT something I am tracking to know my object instance.
Disadvantages:
Small perf degradation
Risk possible "wag of the finger" from Doug Crockford?
Consider this (just run in any js console)
var Animal = function () {
var publicApi = {
Name: 'Generic',
IsAnimal: true,
AnimalHello: animalHello,
GetHelloCount:getHelloCount
};
var helloCount = 0;
function animalHello() {
helloCount++;
console.log(publicApi.Name + ' says hello (animalHello)');
}
function getHelloCount(callback) {
callback.call(helloCount);
}
return publicApi;
};
var Sheep = function (name) {
var publicApi = {
Name: name || 'Woolie',
IsSheep: true,
SheepHello: sheepHello
};
function sheepHello() {
publicApi.AnimalHello();
publicApi.GetHelloCount(function() {
console.log('i (' + publicApi.Name + ') have said hello ' + this + ' times (sheepHello anon callback)');
});
}
publicApi = $.extend(new Animal(), publicApi);
return publicApi;
};
var sheepie = new Sheep('Sheepie');
var lambie = new Sheep('Lambie');
sheepie.AnimalHello();
sheepie.SheepHello();
lambie.SheepHello();
My question is what are the drawbacks to this approach that I am not seeing? Is this a good approach?
Thanks!
[update]
Thanks for the great responses. Wish I could give everyone the bounty. It was what I was looking for. Basically what I thought. I would never use module pattern to construct more than a few instances of something. Usually only a couple. The reason I think it has its advantages is whatever small perf degradation you see is recaptured in the simplicity of the coding experience. We have a LOT of code to write these days. We also have to reuse other peoples' code and personally I appreciate when someone has taken the time to create a nice elegant pattern rather than dogmatically adhering to prototypal inheritance when it makes sense.
I think it boils down to the issue of performance. You mentioned that there is small performance degradation, but this really depends on scale of the application(2 sheep vs 1000 sheep). Prototypal inheritance should not be ignored and we can create an effective module pattern using a mix of functional and prototypal inheritance.
As mentioned in the post JS - Why use Prototype?,
one of the beauties of prototype is that you only need to initialize the prototypal members only once,
whereas members within the constructor are created for each instance.
In fact, you can access prototype directly without creating a new object.
Array.prototype.reverse.call([1,2,3,4]);
//=> [4,3,2,1]
function add() {
//convert arguments into array
var arr = Array.prototype.slice.call(arguments),
sum = 0;
for(var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
add(1,2,3,4,5);
//=> 15
In your functions, there is extra overhead to create a completely new
Animal and sheep each time a constructor is invoked. Some members such as Animal.name are created with each instance, but we know
that Animal.name is static so it would be better to instantiate it once. Since your code implies that Animal.name
should be the same across all animals, it is easy to update Animal.name for all instance simply by updating Animal.prototype.name if we moved
it to the prototype.
Consider this
var animals = [];
for(var i = 0; i < 1000; i++) {
animals.push(new Animal());
}
Functional inheritance/Module Pattern
function Animal() {
return {
name : 'Generic',
updateName : function(name) {
this.name = name;
}
}
}
//update all animal names which should be the same
for(var i = 0;i < animals.length; i++) {
animals[i].updateName('NewName'); //1000 invocations !
}
vs. Prototype
Animal.prototype = {
name: 'Generic',
updateName : function(name) {
this.name = name
};
//update all animal names which should be the same
Animal.prototype.updateName('NewName'); //executed only once :)
As shown above with your currently module pattern we lose effeciency in
updating properties that should be in common to all members.
If you are concered about visibility, I would use the same modular method you are currently using to encapsulate private members but also use
priviledged members for accessing these members should they need to be reached. Priviledged members are public members that provide an interface to access private variables. Finally add common members to the prototype.
Of course going this route, you will need to keep track of this.
It is true that in your implementation there is
No needing to track the 'this' pointer via $.proxy(fn, this) in callbacks
No more var that = this, etc. with event handlers, etc. Whenever I see a 'this', I know it is context that is being passed into a callback, it is NOT something I am tracking to know my object instance.
, but you are are creating a very large object each time which will consume more memory in comparison to using some prototypal inheritance.
Event Delegation as Analogy
An analogy to gaining performance by using prototypes is improved performance by using event delegation when manipulating the DOM.Event Delegation in Javascript
Lets say you have a large grocery list.Yum.
<ul ="grocery-list">
<li>Broccoli</li>
<li>Milk</li>
<li>Cheese</li>
<li>Oreos</li>
<li>Carrots</li>
<li>Beef</li>
<li>Chicken</li>
<li>Ice Cream</li>
<li>Pizza</li>
<li>Apple Pie</li>
</ul>
Let's say that you want to log the item you click on.
One implementation would be to attach an event handler to every item(bad), but if our list is very long there will be a lot of events to manage.
var list = document.getElementById('grocery-list'),
groceries = list.getElementsByTagName('LI');
//bad esp. when there are too many list elements
for(var i = 0; i < groceries.length; i++) {
groceries[i].onclick = function() {
console.log(this.innerHTML);
}
}
Another implementation would be to attach one event handler to the parent(good) and have that one parent handle all the clicks.
As you can see this is similar to using a prototype for common functionality and significantly improves performance
//one event handler to manage child elements
list.onclick = function(e) {
var target = e.target || e.srcElement;
if(target.tagName = 'LI') {
console.log(target.innerHTML);
}
}
Rewrite using Combination of Functional/Prototypal Inheritance
I think the combination of functional/prototypal inheritance can be written in an easy understandable manner.
I have rewritten your code using the techniques described above.
var Animal = function () {
var helloCount = 0;
var self = this;
//priviledge methods
this.AnimalHello = function() {
helloCount++;
console.log(self.Name + ' says hello (animalHello)');
};
this.GetHelloCount = function (callback) {
callback.call(null, helloCount);
}
};
Animal.prototype = {
Name: 'Generic',
IsAnimal: true
};
var Sheep = function (name) {
var sheep = new Animal();
//use parasitic inheritance to extend sheep
//http://www.crockford.com/javascript/inheritance.html
sheep.Name = name || 'Woolie'
sheep.SheepHello = function() {
this.AnimalHello();
var self = this;
this.GetHelloCount(function(count) {
console.log('i (' + self.Name + ') have said hello ' + count + ' times (sheepHello anon callback)');
});
}
return sheep;
};
Sheep.prototype = new Animal();
Sheep.prototype.isSheep = true;
var sheepie = new Sheep('Sheepie');
var lambie = new Sheep('Lambie');
sheepie.AnimalHello();
sheepie.SheepHello();
lambie.SheepHello();
Conclusion
The takeaway is to use both prototypal and functional inheritance to their advantages both to tackle performance and visibility issues.
Lastly, if you are working on a small JavaScript applications and these performance issues are not a concern,
then your method would be viable approach.
a module-pattern-esque constructor pattern
This is known as parasitic inheritance or functional inheritance.
For me the advantages are:
Very clear public and private scope (easy to understand this code and the api)
The same holds true for the classical constructor pattern. Btw, in your current code it's not super clear whether animalHello and getHelloCount are supposed to be private or not. Defining them right in the exported object literal might be better if you care about that.
No needing to track the 'this' pointer via $.proxy(fn, this) in callbacks
No more var that = this, etc. with event handlers, etc. Whenever I see a 'this', I know it is context that is being passed into a callback, it is NOT something I am tracking to know my object instance.
That's basically the same. You either use a that dereference or binding to solve this problem. And I don't see this as a huge disadvantage, since the situation where you'd use object "methods" directly as callbacks are pretty rare - and apart from the context you often want to feed additional arguments. Btw, you're using a that reference as well in your code, it's called publicApi there.
Why do programmers not use a module pattern for non-singleton js classes?
Now, you've named some disadvantages yourself already. Additionally, you are loosing prototypical inheritance - with all its advantages (simplicity, dynamism, instanceof, …). Of course, there are cases where they don't apply, and your factory function is perfectly fine. It is indeed used in these cases.
publicApi = $.extend(new Animal(), publicApi);
…
… new Sheep('Sheepie');
These parts of your code are a little confusing as well. You are overwriting the variable with a different object here, and it happens in the middle-to-end of your code. It would be better to see this as a "declaration" (you're inheriting the parent properties here!) and put it at the top of your function - right as var publicApi = $.extend(Animal(), {…});
Also, you should not use the new keyword here. You do not use the functions as constructors, and you don't want to create instances that inherit from Animal.prototype (which slows down your execution). Also, it confuses people that might expect prototypical inheritance from that constructor invocation with new. For clarity, you even might rename the functions to makeAnimal and makeSheep.
What would be a comparable approach to this in nodejs?
This design pattern is completely environment-independent. It will work in Node.js just as like as at the client and in every other EcmaScript implementation. Some aspects of it even are language-independent.
With your approach, you wont be able to override functions and call the super function so conveniently.
function foo ()
{
}
foo.prototype.GetValue = function ()
{
return 1;
}
function Bar ()
{
}
Bar.prototype = new foo();
Bar.prototype.GetValue = function ()
{
return 2 + foo.prototype.GetValue.apply(this, arguments);
}
Also, in the prototype approach, you can share data among all the instances of the object.
function foo ()
{
}
//shared data object is shared among all instance of foo.
foo.prototype.sharedData = {
}
var a = new foo();
var b = new foo();
console.log(a.sharedData === b.sharedData); //returns true
a.sharedData.value = 1;
console.log(b.sharedData.value); //returns 1
One more advantage of the prototype approach would be to save memory.
function foo ()
{
}
foo.prototype.GetValue = function ()
{
return 1;
}
var a = new foo();
var b = new foo();
console.log(a.GetValue === b.GetValue); //returns true
Whereas in of your approach,
var a = new Animal();
var b = new Animal();
console.log(a.AnimalHello === b.AnimalHello) //returns false
This means with each new object, a new instance of the functions are created where as it is shared among all objects incase of prototype approach.
This wont make much difference incase of few instances but when large number of instances are created, it would show a considerable difference.
Also, one more powerful feature of prototype would be once all objects are created, you can still change the properties among all objects at once (only if they are not altered after object creation).
function foo ()
{
}
foo.prototype.name = "world";
var a = new foo ();
var b = new foo ();
var c = new foo();
c.name = "bar";
foo.prototype.name = "hello";
console.log(a.name); //returns 'hello'
console.log(b.name); //returns 'hello'
console.log(c.name); //returns 'bar' since has been altered after object creation
Conclusion:
If the above mentioned advantages of the prototype approach are not so useful for your application, your approach would be better.

this.method = function(){} VS obj.prototype.method = function (){}

As a c#/.net dev, I love to toy around with JavaScript in my spare time -- creating my own libraries/frameworks and such. Admittedly, they're not much (really nothing more than a loose collections of functions), but the purpose is to learn; not for other people to use.
I usually extend a basic JavaScript object this way
obj = function () {
//basic object stuff
this.method = function () {
//other stuff
};
return this;
};
This allows me to create other objects and chain methods together, which is really slick:
obj('arg1').method();
Two Examples: jQuery Knock-off, List-Item Sorter
However, I have recently seen, in much more function code than my own, objects accomplish the same functionality this way:
function obj(){
//stuff
}
obj.prototype.method = function () {
//stuff
};
Example: Reddit Chrome Extension
Both ways seem to accomplish the same end, and I'm not partial to the look of either syntax. Is there a particular situation where one would be more useful than the other? What do these methods offer that makes them more desirable than the other?
Edit
Consider the following code:
var dice = function (sides) {
this.roll(){
return 4 //guaranteed to be random
}
};
var d1 = dice(6);
d1.roll() // 4;
var d2 = dice(20);
d2.roll() // 4
Are d1 and d2 different objects, as they appear to me? Or are they pointers/nicknames to one object (var dice)?
this.method = function(){};
Only works for that specific instance.
Obj.prototype.method = function(){};
Will work for every instance of Obj
Though in order to take advantage of prototype you should do
var o = new Obj(); // Note that functions intended to be used with "new" should be capitalized
o.method();
Dice Example
I'll assume you intended to return this in your dice() function.
That example is not really common, because calling a function does not create a new object. In your dice case you would be assigning a method to this, which inside the function is window the global object, and then returning it.
The outcome would be the same object (window) in both d1 and d2, with a method roll which would be reassigned in the 2nd call.
To achieve what you want you should create the instances with new, like this:
var d1 = new Dice(6); // remember capitalization is important here
var d2 = new Dice(20);
This will however create 2 roll functions, which is correct but wastes memory since the function can be shared by doing:
Dice.prototype.roll = function() { /* return random awesomeness */ };
Hope that clarifies things

What's the best way to create a JavaScript namespace? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have not yet found a common way on the Internet for creating a namespace in JavaScript.
What's the best way to create a namespace (and please list any downfalls that particular approach might have).
(function() {
var usefulVariable;
var foo = {
bar:function(){ alert('hi') }
};
// leak into global namespace
window.foo = foo;
})();
Only foo is exposed to the global namespace, and it "lives" within your private self executing anon function namespace.
In JavaScript, namespaces can only be achieved through object literals, which can be as simple as this:
var MyNS = {
f1: function() {...},
f2: function() {...}
};
As others have attempted to show, if you want to provide a private scope within your namespace (which is suggested), the following method is the most appropriate:
var MyNS = (function() {
var private1 = "...",
private2 = "...";
return {
f1: function() {...},
f2: function() {...}
}
})();
The book Pro JavaScript Design Patterns (Harmes & Diaz, 2008) provides examples of namespace creation using simple object literals or self-executing anonymous functions, both of which are illustrated in Justin Johnson's excellent answer, and these approaches work well.
Depending on the situation, it might be possible that the namespace already exists and contains members. In such a case, these approaches would destroy any members in the namespace. If this is a concern, one can use an approach similar to this to preserve any existing members, while adding new ones:
var myNamespace = (function(ns) {
ns.f1 = function() { ... };
ns.f2 = function() { ... };
return ns;
})(window.myNamespace || {});
Here, myNamespace is assigned the value returned by the anonymous, self-executing function that receives the parameter ns. As one can see, the value of this parameter is either window.myNamespace or an empty object, depending on whether or not myNamespace has been previously declared.
Here's my favorite way. It's a little unorthodox but it works well.
var MyNamespace = new function(){
this.MY_CONST_ONE = 1;
this.MY_CONST_TWO = 2;
this.MyClass = function (x) {
this.x = x;
}
this.MyOtherClass = function (y) {
this.y = y;
}
} // end of namespace
// ...
var oc = new MyNamespace.MyOtherClass(123);
The interesting thing about it is the closure function is called with new instead of the normal parenthesis, so directly inside of it this refers to the object returned by the function, in other words, the 'namespace' itself.
I generally try to keep it simple and create a global object representing the namespace. If you are using multiple scripts, each declaring the namespace because they might each be used in different applications, then you would probably want to check if the object already exists.
//create the namespace - this will actually obliterate any pre-existing
//object with the same name in the global namespace
//(and this does happen).
//NB ommiting the var keyword automatically chucks the object
//variable into the global namespace - which ordinarily you
//don't want to do
MyNameSpace = {};
//and then create a class/object in the namespace
MyNameSpace.MyClass = {
someProperty: function(){
//do something
},
anotherProperty: function(){
//doing something else
}
};
This is pretty much what everyone else is saying. I'm just giving the really simplistic approach. Main drawback I see is that theoretically the "MyNameSpace" object could already exist - so might want to check that before you create it. Generally, if I'm going to be doing anything more complicated than that I would start thinking of a framework like JQuery or ExtJS which take a lot of pain out of these sort of things.
One more note. Part of the reason why you can't find a common way to do many things in Javascript, like creating namespaces, is that there is always more than one way to skin a cat in Javascript. Most languages are quite proscriptive on how you do things - create classes, are functional or object oriented or procedural. Javascript, on the other hand, is short of keywords and highly flexible. This maybe a good thing or a bad thing - depending on your point of view. But I quite like it.
To share code between scripts, you have to have at least one global variable (unless of course if you would want to do something as silly as appending your variables to an already existing object such as window.Object.
Even if you use the module pattern, you need to have a common place to share code, so, say e.g. you have three scripts:
core.js
utils.js
Then we can in the core.js script file have a module:
(function(global) {
var coreModule = {};
var MY_CONSTANT = 42
var meaningOfLife = function() {
return MY_CONSTANT;
};
coreModule.meaningOfLife = meaningOfLife;
global.myRootNamespace = coreModule;
}(this));
in the utils.js:
(function(root) {
var utilsModule = root.utils = {};
utilsModule.bark = function() {
console.log("WOOF!");
};
}(myRootNamespace));
Here, we see the use of the augmentation module pattern, and namespacing the functionality depending on the nature of the functionality. This specific implementation overwrites the value of the utils property on the myRootNamespace object. However, we can write it so that it does not:
(function(root) {
var utilsModule = root.utils = root.utils || {};
utilsModule.bark = function() {
console.log("WOOF!");
};
}(myRootNamespace));
If one doesn't want to use the module pattern, we can use a simple function to define namespaces for us in a non destructive manner:
var ensureNamespace = function recur(ns, root) {
var parts = typeof ns === 'string' ? ns.split('.') : ns;
var r = root || this;
if (parts[0]) {
var next = parts.shift()
r[next] = r[next] || {};
return recur(parts, r[next]);
}
return r;
};
// maybe another file:
(function(){
var baz = ensureNamespace("foo.bar.baz");
// baz === window.foo.bar.baz;
baz.qux = "Yep...";
}());
see this excellent article for more insight.
You can combine the answers you have received so far and accomplish much;
var Foo; // declare in window scope.
(function(){
var privateVar = "BAR!";
// define in scope of closure where you can make a mess that
// doesn't leak into the window scope.
Foo = {
staticFunc: function(){ return privateVar; }
};
})();
I generally avoid window.xxxx = yyyy; as it does not always play nicely with visual studio intellesense. There may be other issues but none that I know of.
I believe the module pattern has shown that it is the way to go. Object Literal Name-spacing exposes everything to the caller code outside the namespace which is essentially not a very good idea.
If you insist on creating Object Literal Namespaces, read this tutorial. I find it easy and short and I believe is very through:Object Literal Namespace (OLN) in Javascript

Categories

Resources