Hullo! This is my first question!
I am experimenting with the module pattern promoted by Doug Crockford and others. Mostly very happy with it so far, but I am a little unsure about the best way of handling a certain inheritance pattern.
I have it boiled down to a bare bones case using cat and mammal, although my actual intention is to make objects for a tile based game in canvas.
But here is my bare bones 'animals' case using a browser alert:
var ZOO = ZOO || {};
//
ZOO.mammal = function () {
"use strict";
var voice = "squeak.mp3", // default mammal sound
utter = function () {
window.alert(this.voice);
};
//
// public interface
return {
utter: utter,
voice: voice
};
};
//
ZOO.cat = function () {
"use strict";
// hook up ancestor
var thisCat = ZOO.mammal();
thisCat.voice = "miaw.mp3";
return thisCat;
};
//
var felix = ZOO.cat();
felix.utter();
What bothers me about this approach is that I have had to make voice a public property so that cat can modify it.
What I really want is something like 'protected' visibility (from Java, ActionScript etc.), so that cat can modify voice without anyone with access to felix being able to modify it.
Is there a solution?
You can simulate protected visibility (visible to yourself, and child objects) by passing a blank object to your base "class" to serve as the repository for your protected properties. This will allow you to share properties through your inheritance chain, without making them public.
var ZOO = ZOO || {};
ZOO.mammal = function (protectedInfo) {
"use strict";
protectedInfo = protectedInfo || {};
protectedInfo.voice = "squeak.mp3";
// public interface
return {
utter: function () {
alert(protectedInfo.voice);
}
};
};
ZOO.cat = function () {
"use strict";
var protectedInfo = {};
// hook up ancestor
var thisCat = ZOO.mammal(protectedInfo);
protectedInfo.voice = "miaw.mp3";
return thisCat;
};
Here's a live demo
Sidesteping non-answer:
There are some ways to kind of get protected properties in Javascript but they aren't necessarily very idiomatic. If I were you I would first strongly consider either
Using the convention of public properties prefaced with an underscore (ex.: _voice) to denote privacy. Its very simple and is something of a standard among dynamic languages.
Seek an alternate solution without inheritance. Inheritance often complicates and couples stuff to much, hence the old "prefer composition over inheritance" mantra. Javascript has many features, like duck typing and higher order functions, that often let you avoid using inheritance in situations where you would normaly need it in Java
There is a workaround to simulate protected members, where you make public those members for a while, and then you privatise them again. I'm not a big fan of this, but it's a "solution".
I'm just quoting from this SitePoint article:
Adding Protected Members
Splitting a script into multiple modules is a common and convenient
practice. It makes a large codebase much easier to manage, and allows
for bandwidth savings to be made when modules aren’t always required.
But what if we want to share data between different modules? If we
make that data public then we’ll lose the benefits of privacy, but if
we make it private it will only be available to one module. What we
really need are shared private members, and these are known as
protected.
JavaScript doesn’t have protected members as such, but we can
effectively create them by making data temporarily public. To achieve
this, let me first introduce you to two key functions — extend and
privatise — which we’ll define as part of a utility-functions object:
var utils = {
extend : function(root, props) {
for(var key in props) {
if(props.hasOwnProperty(key)) {
root[key] = props[key];
}
} return root;
},
privatise : function(root, prop) {
var data = root[prop];
try { delete root[prop]; } catch(ex) { root[prop] = null; }
return data;
}
};
The extend function simply adds new properties to an object, while the
privatise function copies a property and then deletes the original. We
can use extend in one module to create a public reference to a private
variable, and then use privatise in another module to copy it back to
a private variable and delete the public reference.
So here’s an example of the first module which has two protected
members (including the utils object itself), and one public member. To
keep the code example short, the utility functions are just empty
shells, but they would be identical to the functions I showed you a
moment ago:
var MyModule = (function() {
var myProtectedData = 909;
var utils = {
extend : function(root, props) { },
privatise : function(root, prop) { }
};
this.myPublicData = 42;
return utils.extend(this, { myProtectedData : myProtectedData, utils : utils });
})();
You can see how we’re using a variant of the revealing module pattern,
to return not just the public members, but the protected members as
well. So at this point we have three public members:
MyModule.myProtectedData, MyModule.utils and MyModule.myPublicData.
Now here’s an example of the last module which uses the privatise
function to copy the specified public members back to private
variables, and then delete their public references:
var MyModule = (function() {
var myProtectedData = this.utils.privatise(this, 'myProtectedData');
var utils = this.utils.privatise(this, 'utils');
return this;
}).apply(MyModule);
And once that’s done the protected members are locked inside their
objects, privately available to both the modules, but no longer
available from outside them.
Note that the privatise function relies on having separate arguments
for the object and the property-key, because objects in JavaScript are
passed by reference. So root is a reference to MyModule, and when we
delete a property from it that’s specified by key, we’re deleting that
property from the referenced object.
But if it was like this:
privatise : function(root) {
var data = root;
try { delete root; } catch(ex) { root = null; } return data;
}
And called like this:
var myProtectedData = this.utils.privatise(this.myProtectedData);
Then the public members would not be deleted — the function would
simply delete the reference, not the property it refers to.
The try ... catch construct is also necessary for older IE versions,
in which delete is not supported. In that case we nullify the public
property rather than deleting it, which is obviously not the same, but
has an equivalent end result of negating the member’s public
reference.
Related
I am trying to find best way how to create multiple instances and configure my module according Module pattern.
Currently I have
var Logger = (function () {
// Private members
var _settings = {
json: JSON,
output: console
};
// Private methods
var _log = function (info) {
_settings.output.log(info);
};
var _dump = function (info) {
_log(_settings.json.stringify(info));
};
// Change default settings
var changeSettings = function (settingsArgs) {
if (settingsArgs !== undefined) {
if (settingsArgs.json !== undefined) {
_settings.json = settingsArgs.json;
}
if (settingsArgs.output !== undefined) {
_settings.output = settingsArgs.output;
}
}
};
return {
init: changeSettings,
log: _log,
dump: _dump
};
})();
I have several questions about this pattern.
What is the best way to provide configuration to the module, I simply created setter for private settings fields, but I feel this is not the best way it can be implemented. Please suggest right approach.
How to create multiple instances of my module. As I understood, module commonly used to encapsulate global objects and logic (like singletons), so most of time only one instances of module exists, but I need to have multiple instances. In my case this can be useful for example, I can create one logger ConsoleLogger another one will be AlertLogger the difference is output, but now I can only have one instance.
Please suggest the right way to follow, I have already read a lot of articles but haven't found answers to my questions. Thanks
What you have there is Module used as an Immediately-Invoked-Function-Expressions (IIFE), because of () at the end. Therefor, you are creating instance at class definition time and you can only have a single instance. You could clone one instance and have multiple of them, but that is not a good thing to do.
If you want to have multiple instances, you should remove IIFE expression at the end. Also, you can pass settings as constructor param:
var Logger = function (settingsArgs) {};
Now, you can create multiple instances:
var consoleLogger = new Logger({output: console});
var alertLogger = new Logger({output: alert}); // change this line probably, for this to work _settings.output.log(info);
I'm new to JavaScript and am trying to understand how to use namespaces to avoid naming conflicts. So far, the two most popular methods I've found for creating namespaces are these:
Method 1:
var MYAPPLICATION = {
calculateVat: function (base) {
return base * 1.21;
},
product: function (price) {
this.price = price;
this.getPrice = function(){
return this.price;
};
},
doCalculations: function () {
var p = new MYAPPLICATION.product(100);
alert(this.calculateVat(p.getPrice()));
}
}
Method 2:
var DED = (function() {
var private_var;
function private_method()
{
// do stuff here
}
return {
method_1 : function()
{
// do stuff here
},
method_2 : function()
{
// do stuff here
}
};
})();
Is the difference that the second method allows you to have private methods and variables, since only what is inside of the object being returned will be globally accessible? Which of these methods is best (or is there a better way)?
If you write an API for other people, I think method two is better. Example:jQuery.
In a web page, I prefer method one. Example:stackoverflow
In method two, you can not read and write functions and variables that is private, so if there is a bug, you can not read something by developer-tools for debug.
Second method is called 'module' pattern. Makes it comfortable for developers to use your code. Self-invoking function creates scope, so you only expose methods that you want to make public by returning object that contains references to those methods (public API). Those methods can have a lot of private helper functions and variables that you keep private for your own use. Most of the libraries are written this way. It's generally good to structure your library like that.
Here's a link to the website that explains it well : http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
First method is just the way to put all the related functions together. You can make those for personal use in your module. Example:
Calc.add(5,5), Calc.subtract(3,2), Calc.multiply(3,3);
add, subtract, multiply share same namespace because they are related.
I'm using the javascript module pattern, and have this so far:
var APP;
if(APP == undefined) {
APP = {};
}
APP = (function() {
var userId = -1;
var privateVar = '';
var _init = function($userId) {
userId = $userId;
};
var _publicMethod = function($id){
privateVar = id;
};
return {
init = function($userId) {
_init($userId);
},
publicMethod = function($id) {
_publicMethod($id);
}
};
})();
I then have a common utils module:
APP.utils = (function(){
})();
And then per page I am planning on having a module, so I don't wireup events (button clicks etc) for no reason on pages where these DOM elements don't event exist:
APP.homePage = (function(){
return {
};
})();
So each module will have a init() method that I will call on the page to run things that have to be run (e.g. wiring up events, setting variables like say userId etc):
$(document).ready(function() {
APP.init(<%= user.id %>);
APP.homePage.init('abc');
});
So now if the files get too big, I can break them out into separate files also.
What if one module needs to call another, I guess the only way for this to work is to do this via the public api right?
e.g. what if homePage needs userId, should I pass that in the homePage#init method?
How is my coding style, any obvious style that is not considered best practise?
Any comments on this approach? Is it good in general?
What if one module needs to call another, I guess the only way for this to work is to do this via the public api right?
Yes
e.g. what if homePage needs userId, should I pass that in the homePage#init method?
No. I'd not repeat the userId code in all modules, but offer a public getter for it in the default module.
Any comments on coding
This code
var APP;
if(APP == undefined) {
APP = {};
}
APP = ...
is quite useless. You don't need to check for object existance here, because you overwrite it anyway. That also means that this code must be the first to execute. If you want to make the modules independent from load order, you'd need to use something like
var APP = (function(a) {
var private_vars; // ...
a.init = ...
a.publicMethod = ... // add them to the object instead of creating new one
a.getPrivate = function() {
return private_vars;
};
return a;
})(APP || {}); // create one iff not already existing
// other file:
var APP = APP || {};
APP.utils = ... // add object to namespace
The code
var _publicMethod = function($id){
privateVar = id;
};
looks a bit odd. First, the underscore usually denotes a semiprivate (public-but-not-to-be-used) attribute of objects and should not be used for variable names. That's not the case in here as the function will be exposed as the "publicmethod" property of APP. Use the underscore there if you want it. Second, there is no need to use a function expression here. The code is in the module's local scope, and using a function declaration both makes it available everywhere in that scope and allows naming the function. You should use
function publicMethod($id) {
privateVar = id;
}
a.publicMethod = publicMethod;
The module pattern is, in my opinion, a really nice way to organize your code. To answer your questions:
1) Yes, your modules can only access methods and properties of other modules which have been exposed in the object they return.
2) I think your coding style looks pretty good. I'd make these changes:
APP = (function() {
var _userId = -1;
var _privateVar = '';
var init = function($userId) {
_userId = $userId;
};
var publicMethod = function($id){
_privateVar = id;
};
return {
init : init,
publicMethod : _publicMethod
};
})();
First, underscores are generally meant to denote "private" properties or methods. Secondly, you can do away with the extra functions in the object being returned and just point straight to the methods or properties you care about. This is generally referred to as the "Revealing Module Pattern", because even the public methods aren't defined within the returned object - they're simply referenced.
3) This approach is definitely a nice way to encapsulate code. You get the benefit of private and privileged methods, and you generally end up with a nicer API because you're only exposing things that need to be public.
Well done.
Introductory reading:
Prototypes as "classes"
OO JS
Following the patterns described above I create libraries/APIs as the following
var Proto = {
constructor: function () {
this.works = true;
},
method: function () {
return this.works;
}
};
Now for library users to interact with my prototypes (which do not supply factory functions) they have to instantiate and initialize the object
// instantiate
var p = Object.create(Proto);
// initialize
p.constructor();
This is an unfriendly and verbose way of forcing users to instantiate and initialize my objects.
personally since I use pd in all my applications I have the following sugar
// instantiate or initialize
var p = Proto.new();
// or without bolting onto Object.prototype
var p = pd.new(Proto);
However I think it's unkind to force pd onto users so I'm not sure what's the best way to make my libraries usable.
People create new instances of Proto and call .constructor themself
Force people to use pd
Give .create style factory functions
Give up and use new <Function> and .prototype
1 and 2 have already been mentioned.
3 would basically be
Proto.create = pd.new.bind(pd, Proto);
4 would make me sad but confirming to a known standard way of doing things increases usability.
Generally when using non-standard OO patterns what are the easiest mechanisms to allow people to use my library in their application?
I'm currently tempted to say
// here is my Prototype
Proto;
// here is how you instantiate a new instance
var p = Object.create(Proto);
// here is how you initialize it
// yes instantiation and initialization are seperate and should be.
p.constructor();
// Want sugar, use pd.new
For now, you probably make it easiest on your library clients if you use a small API that helps you with building a traditional constructor function, using syntax that looks almost like prototypes-as-classes. Example API usage:
// Superclass
var Person = Class.extend({
constructor: function (name) {
this.name = name;
},
describe: function() {
return "Person called "+this.name;
}
});
// Subclass
var Worker = Person.extend({
constructor: function (name, title) {
Worker.super.constructor.call(this, name);
this.title = title;
},
describe: function () {
return Worker.super.describe.call(this)+" ("+this.title+")";
}
});
var jane = new Worker("Jane", "CTO");
Implementations:
Simple JavaScript Inheritance
I’ve reimplemented Resig’s API, in a way that is possibly easier to understand: rauschma/class-js
I think the way to go is providing the new(Prototype, [arguments]) function as per the "use pd" option. It should even not be that bad from a dependency point of view (since you could have packaged this function separately anyway and is has just a couple of lines of code)
Offering a special function also fits in a sort of historic perspective. If you go way back to Smalltalk or even in more recent cases like Python you have separate functions for object creation (new) and initialization (init, the constructor) and the only only reason we don't notice the separation is because they provide syntactic sugar for object instantiation.
I'm interesting in improving my javascript code to be properly OOP.... currently I tend to do something like this:
jQuery(document).ready(function () {
Page.form = (function () {
return {
//generate a new PDF
generatePDF: function () {
},
//Update the list of PDFs available for download
updatePDFDownloads: function () {
},
/*
* Field specific functionality
*/
field: (function () {
return {
//show the edit prompt
edit: function (id, name) {
},
//refresh the value of a field with the latest from the database
refresh: function (id) {
}
};
}())
};
}());
});
In the end it's just mainly organized functions I suppose... what's a good resource where I can learn to program javascript in an OOP manner, or what suggestions would you have for improving my current style of programming?
It seems like I should do a sort of model prototype and have my form object inherit from that prototype.
(I'm using jQuery instead of $ because of conflicts with prototypeJS)
Your question is quite broad so I don't think a complete answer is possible here. But here are a few points.
Regarding the code you have shown. You're jumping a couple of redundant hoops.
Unless you're accessing the DOM in some way, there is no need to wrap your code in jQuery(document).ready()
There is no need to return an object from a self calling anonymous function unless you're closing over some private functions or data
The object you have created can be created more simply (a good thing) like this
var Page = {
form: {
//generate a new PDF
generatePDF: function () {
},
//Update the list of PDFs available for download
updatePDFDownloads: function () {
},
/*
* Field specific functionality
*/
field: {
//show the edit prompt
edit: function (id, name) {
},
//refresh the value of a field with the latest from the database
refresh: function (id) {
}
}
}
};
It's easier to read and less confusing, only do things that buy you something. see cargo cult programming
Here's an example using a self calling anonymous function to create private members
var Obj = (function() {
privateFunction( param ) {
// do something with param
}
var privateVar = 10;
return {
// publicMethod has access to privateFunction and privateVar
publicMethod: function() {
return privateFunction( privateVar );
}
}
})();
The structure you have used, object literals are very good, as you say, at grouping a set of functions (methods) and properties. This is a kind of namespace. It is also a way of creating a Singleton. You may also want to create many objects of the same Class.
JavaScript doesn't have classes like traditional OO languages (I'll get to that) but at the simplest level it's very easy to create a 'template' for creating objects of a particular type. These 'templates' are normal functions called constructors.
// a constructor
// it creates a drink with a particular thirst quenchingness
function Drink( quenchingness ) {
this.quenchingness = quenchingness;
}
// all drinks created with the Drink constructor get the chill method
// which works on their own particular quenchingness
Drink.prototype.chill = function() {
this.quenchingness *= 2; //twice as thirst quenching
}
var orange = new Drink( 10 );
var beer = new Drink( 125 );
var i_will_have = ( orange.quenchingness > beer.quenchingness )
? orange
: beer; //beer
var beer2 = new Drink( 125 );
beer2.chill();
var i_will_have = ( beer2.quenchingness > beer.quenchingness )
? beer2
: beer; //beer2 - it's been chilled!
There's a lot to know about constructors. You'll have to search around. There are lots of examples on SO.
Inheritance, the foundation of OO, is not that intuitive in js because it is prototypal. I won't go into that here because you will more than likely not use js's native prototypal inheritance paradigm directly.
This is because there are libraries that mimic classical inheritance very effectively, Prototype (inheritance) or mootools (Class) for example. There are others.
Many say that inheritance is overused in OO and that you should favour composition and this brings me to what I initially set out to recommend when I started this rambling answer.
Design patterns in JavaScript are as useful as in any OO language and you should familiarise yourself with them
I recommend you read Pro JavaScript Design Patterns.
There, that's it
Some good sources for Object-Oriented JavaScript and JavaScript in general...
Online Articles
How to "properly" create a custom object in JavaScript?
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
http://mckoss.com/jscript/object.htm
http://ejohn.org/blog/simple-javascript-inheritance/
JavaScript: How To Get Private, Privileged, Public And Static Members (Properties And Methods)
Books
JavaScript: The Good Parts - Douglas Crockford
Object-Oriented JavaScript - Stoyan Stefanov
I hope this helps.
Hristo
There isn't one correct way... Some people use a framework to define their object, I like to just extend prototype directly. Anyhow, I wanted to say that Oran Looney has some good posts on OO mechanics in JS:
http://oranlooney.com/classes-and-objects-javascript/
Its also worth looking at his other articles:
http://oranlooney.com/deep-copy-javascript/
http://oranlooney.com/functional-javascript/
The top 3 I suggest to read is
JavaScript and Object Oriented Programming (OOP)
Classical Inheritance in JavaScript
Prototypal Inheritance in JavaScript
Have a nice reading!
The code we are using follows this basic structure:
//Create and define Global NameSpace Object
( function(GlobalObject, $, undefined)
{
GlobalObject.Method = function()
{
///<summary></summary>
}
}) (GlobalObject = GlobalObject || {}, jQuery);
//New object for specific functionality
( function(Functionality.Events, $, undefined)
{
//Member Variables
var Variable; // (Used for) , (type)
// Initialize
GlobalObject.Functionality.Events.Init = function()
{
///<summary></summary>
}
// public method
this.PublicMethod = function(oParam)
{
///<summary></summary>
///<param type=""></param>
}
// protected method (typically define in global object, but can be made available from here)
GlobalObject.Functionality.ProtectedMethod = function()
{
///<summary></summary>
}
// internal method (typically define in global object, but can be made available from here)
GlobalObject.InternalMethod = function()
{
///<summary></summary>
}
// private method
var privateMethod = function()
{
///<summary></summary>
}
}) (GlobalObject.Funcitonality.Events = GlobalObject.Funcitonality.Events || {}, jQuery )
The strength to this is that it initializes the Global object automatically, allows you to maintain the intergrity of your code, and organizes each piece of functionality into a specific grouping by your definition. This structure is solid, presenting all of the basic syntactical things you would expect from OOP without the key words. Even setting up intelisense is possible with javascript, and then defining each peice and referencing them makes writing javascript cleaner and more manageable. Hope this layout helps!
I dont think it matters what language you use, good OOP is good OOP. I like to split up my concerns as much as possible by using an MVC architecture. Since JavaScript is very event based, I also use the observer design pattern mostly.
Heres a tutorial you can read about MVC using jQuery.