Use of prototype for single instance functions in JavaScript - javascript

For performance optimization I'm using a single JavaScript file to handle all the pages of the website I'm working on.
The basic structure I'm using is as followed:
(function($) {
// Shared functions ...
// A function for every page
function Page1() {
}
Page1.prototype = {
init: function() {
//...
},
//more functions
};
// more pages
$(document).ready(function() {
if ($('#page1uniqueidentifier').length) {
var page1 = new Page1();
page1.init();
}
// more pages
}
}) (jQuery);
I'm not an experienced JavaScript programmer so I've been searching a lot about best practices and different ways of structuring my code and I've ended up choosing this one but I'm not really sure about it and I have a few questions:
Is it worth it to use prototype if I'm never gonna have more than a single instance of a page? I think I understand how prototype works and that I'm not gaining any performance there. But I'm using it just as a best practice because in the case different instances would exist, these functions would be the same in every instance.
Is there a better way to structure the code?
Should I put the call of the init function inside the constructor and then only call new Page1()?
function Page1() {
this.init();
}
if ($('#page1uniqueidentifier').length) {
new Page1();
}

For performance optimization I'm using a single JavaScript file to
handle all the pages of the website I'm working on
That makes no sense. You should separate code into files, and then run all your js files thru a minimizer/concatenator to package it up.
Anyway, to answer your questions,
if you are only going to have 1, then prototype won't buy you anything. However, if you are going to use more than 1, would you go back and change it? Plus, using prototype wont hurt you either, so you might as well do it for learning.
You should create the files that make sense according to the functionality implemented. I would separate your object definition into its own file, for example, so when you look at that file, all you see is the code for that object.
If you have a constructor function, you don't really need init, do you?

Related

Is calling a property's method from another method of the same object in this manner ok?

Can someone help me understand why the code below works and if this is an acceptable pattern to use?
Without getting into it too much I have a basic state machine functionality inside an object called states in a simple browser game I am making and I able to trigger event transitions by calling states.event('someEvent') from within the states object itself. For instance if the update method of a given state, say states.someState.actions.onUpdate() is running it can call states.event('someNewEvent'). Doing it this way is not something I need to do, I did it accidentally but I was very confused by the fact that it worked. So the code below is that logic/functionality which I don't understand reduced down to a simple example.
I can't seen to find any information that would explain this type of pattern.
Everywhere online would seem to suggest that I write "this.printText()" instead of "myObj.printText()" but it only prints when I do it the way I have below.
This seems like it might be bad practice, at the very least it would be because I don't understand quite why it works... Any help would be appreciated. I struggle a lot with javascript coming from C# in unity game engine.
let myObj = {
printText: function() {
console.log('I thought this would not print');
},
myProperty: {
toPrint: function () {
myObj.printText();
}
}
}
myObj.myProperty.toPrint();

Architecture for creating a JavaScript framework

Around one year ago we started a web system that over the time has grown quite a bit. From the beginning the goal was to build reusable code that would speed up the development of future projects, and it has. With every new project, the reusable code from the previous was taken and build upon it.
At the moment, the server side code is really clean, and there is a clear separation between the "framework" (generic functionality) and the project specific logic.
However, the javascript has grown out of control. For the page specific javascript (button events, ajax calls, etc.) we've been using closures and the module pattern. But the javascript common files (the ones we import in every page), are full of functions with no association between them beyond some similarities on the names.
Because of this I'm now trying to build a sort of framework (easily reusable and maintainable code) encapsulating the logic and functions we already have. It should be one "core" object and several optional "extensions". They would be in separate files to improve the order of the code. Specifically, I'm trying to achieve the following:
Encapsulation of the code to prevent name collisions. We are very comfortable with the private/public separation of the closures.
Extendable functionality, something like the open/close principle. The tricky part here is that an extension might want to access a private method of the core.
I've been reading a lot on OO in javascript, and I've even tried to understand how jQuery does it, but I'm still unable to get my head around it. For the architectural side, it seems that I should be building a module or service framework, but the ones I've found are much more complex than what I want to achieve.
If it weren't for the tricky part mentioned earlier, a simple $.extension() would do, but I'm stuck in the how to access a core private method from an extension part. In short, my question would be: Is there a recommended architecture in javascript to build something like the following example?
var framework = function () {
//Private variable
var internalState = 1;
//Private method
var validState = function () { ... }
//Public methods
return {
commonTask1: function () { ... },
commonTask2: function () { ... }
}
}();
framework.addMoreFunctionality(function () {
var specificData = '';
return {
extensionMethod: function () {
//TRICKY PART HERE
if (core.validState()) { ... }
}
}
}());
Just return a function from the framework module.
return {
isValidState: function() { ... }
commonTask1: function () { ... },
commonTask2: function () { ... }
}
The isValidState function could then check the internal state.
// isValidState
function() {
if (validState()) {
return true;
}
return false;
}
Check if the state is valid then by calling core.isValidState(); Like this you will not get any reference to any "private" variable inside the framework core because the functions returns a bool and not a direct reference to any objects.
Have you explored DOJO ? It has module system, a build system and very elaborate OO framework implemented.
You can have your own modules / "base Dijits" that will help you implement "generic modules/widgets" and then extend them per-project, by writing / adding specific capabilities the way you have described.
DOJO is not exactly in Vogue, but if your application deals with forms like interface, then it's definitely a candidate.

A JavaScript concatenator to help data hiding under modularization?

I previously run into the problems of data hiding under modularization in JavaScript. Please see the links below:
Module pattern- How to split the code for one module into different js files?
JavaScript - extract out function while keeping it private
To illustrate the problem, see the example below. My goal is to split my long js file into 2 files, but some functions need to access some private variables:
first.js:
(function(context) {
var parentPrivate = 'parentPrivate';
})(window.myGlobalNamespace);
second.js:
(function(context) {
this.childFunction = console.log('trying to access parent private field: ' + parentPriavte);
}(window.myGlobalNamespace.subNamspace);
Now this wouldn't work because child doesn't have access to parent. One solution is to make parentPrivate publicly visible, but that is unacceptable in my case.
Quoting #Louis who gave an answer for one of the previous questions:
"We can't have a field that's accessible by child but not to outside
public (i.e. protected). Is there any way to achieve that?"
If you want modularization (i.e. you want the child to be coded
separately from the parent), I do not believe this is possible in
JavaScript. It would be possible to have child and parent operate in
the same closure but then this would not be modular. This is true with
or without RequireJS.
The problem is that the parent and the child are not inside the same closure. Therefore I'm thinking, does it make sense to create a library that puts files into the same closure?
Something like:
concatenator.putIntoOneClosure(["public/js/first.js", "public/js/second.js"]);
Of course we can take in more arguments to specify namespaces etc. Note that it is not the same functionality we get from RequireJS. RequireJS achieves modularization while this concatenator focuses on data hiding under the condition of modularization.
So does any of the above make sense? Or am I missing out some important points? Any thoughts are welcomed.
If you need things available in two separate files, then you can't have true privacy... however, something similar to this may work for you:
first.js:
(function(context) {
var sharedProperties = {
sharedProp1: "This is shared"
};
function alertSharedProp1() {
alert (sharedProperties.sharedProp1)
}
window[context] = {
sharedProperties: sharedProperties,
alertSharedProp1: alertSharedProp1
};
})("myGlobalNamespace");
second.js:
(function(parent, context) {
// CHANGED: `this` doesn't do what you think it does here.
var childFunction = function() {
console.log('trying to access parent private field: ' + window.myGlobalNamespace.sharedProperties.sharedProp1);
};
window[parent][context] = {
childFunction: childFunction
};
}("myGlobalNamespace", "subNamspace"));
window.myGlobalNamespace.subNamspace.childFunction();
Edit detailed answer based on comments
What I did was to set up a source file that looked like this:
master.js
(function() {
##include: file1.js##
##include: file2.js##
}());
Then I wrote a script (in windows scripting, in my case) that read in master.js and then read through line by line looking for the ##include: filename.js## lines. When it found such a line it read in the include file and just dumped it out.
My particular needs were special since I was writing a browser plugin that needed to work in three different browsers and had to be wrapped up separately, yet for my own sanity I wanted separate files to work with.

Gloal Abatement - Using a Single Object Literal

So I just need a sanity check on the way in which I layout my code for an application. I'm always keen to learn better approaches.
I basically use an Object Literal to organise my code meaning that I have one single global variable. Then for each section of the application I create a separate object - something like:
var MYAPP = {
init : function() {
//site wide common js
},
sections : {
homepage : function() {
//homepage js
},
anotherpage : function() {
//another page js
tools.usefultool();
}
},
tools : {
usefultool : function() {
//useful reuseable method
}
}
};
My question is while this helps code organisation, I'm wondering about objects being initialised but never used. For example - if I'm on a site's homepage I'll just call MYAPP.sections.homepage() . I don't actually need any of the other objects so I'm wondering - does this structure have a performance implication? Is there a better way? The structure closely follows the the great Rebecca Murphy article "Using Object to Organise Your Code" (http://blog.rebeccamurphey.com/2009/10/15/using-objects-to-organize-your-code).
Thanks!
Yes, there's always a performance hit in unused code as the parser has to actually interpret the code even if it's not executed. But any performance hit here is so minute that you're never going to notice it. The only real hit in unused code like this is in the bandwidth required to download it. If you have a 100kb file downloaded that you never use then you're wasting the time to download that file.

JavaScript structure, right way?

Iam trying to get better in javascript coding. Away from 1000 lines of code in one file. But iam not sure if this is the "right" way:
RequireJS to load files when needed inside "boot.js":
require([
"library/jquery.form/jquery.form",
"app/eventManager",
"app/myapp"
], function() {
$(function() {
MyApp.init();
});
});
MyApp.js
var MyApp = {
init: function() {
MyApp.mainController();
},
// this is our controller, only load stuff needed..
mainController: function() {
//controller = set from php/zendframework
switch (controller) {
case 'admin':
MyApp.initAdmin();
break;
default:
break;
}
},
// action for admin controller
initAdmin: function() {
//lazy load
require(["app/admin/admin"], function(){
MyApp.admin.init();
});
}};
MyApp.admin.js
MyApp.admin = {
init : function() {
if (permisson != 'admin') {
console.log('Permission denied.');
return false;
}
MyApp.admin.dashboard.init();
}
};
MyApp.admin.dashboard = {
init: function() {
MyApp.admin.dashboard.connectEventHandlers();
MyApp.admin.dashboard.connectEvents();
MyApp.admin.dashboard.getUserList('#admin-user-list');
},
connectEvents: function () {
EventManager.subscribe("doClearCache", function() {
MyApp.admin.dashboard.doClearCache(url);
});
EventManager.subscribe("doDeleteUser", function() {
MyApp.admin.dashboard.doDeleteUser(url);
});
},
What other "styles" are common? or this a goodway to structure code? THere a lot of examples in the net, but i was not able to find "real life" code..
And one of biggest "problems" when does i need ".prototype" ?
JavaScript Patterns is a good reference for various ways of structuring code.
It would also be a good idea to study the source code of libraries such as jQuery.
One change I would make to your code is to avoid repeating 'event' strings everywhere.
You could reduce this by doing something like:
var app = {
events : {
someEvent : "someEvent"
}
}
EventManager.subscribe(app.events.someEvent, someFn);
EventManager.publish(app.events.someEvent);
I would also avoid calling console.log directly and use a wrapper such as this which provides a fallback if not console is available
N.B Angus Croll has a decent blog where he mentions js structure/namespacing etc
and there is some really good knowledge being shared over at JsMentors from well versed js ninjas
I defer to Douglass Crockford on all matters pertaining to JavaScript best practices.
Here is his homepage: http://javascript.crockford.com/.
Here is a great book on what to do and what not to do in JavaScript. http://www.amazon.com/exec/obidos/ASIN/0596517742/wrrrldwideweb
Here is his amazing tool which can automatically tell you if you are employing any worst practices. http://www.jslint.com/
As to the prototype question, you use prototype when you want to employ prototypal inheritance, or create a "static" class function which will be present for all instances of that class without consuming memory for each instance.
Require.js is great tool, you can use it also on the client side. But be careful when you use it on mobile. In such case you should either use the editor to navigate better in one file or use thing like sprocket. It is a "precompiler", does not put any additional library to your code.
I passed through your sliced up code. Probably you should define the different parts as modules, read the requirejs documentation for defining modules, it gives good assistance.
But think twice whether you really need for organizing your code an extra library.
In case you are building something more complex, for example with multiple product modules and sub modules, I recommend creating a context hierachy for your modules. Also make the UI components to be self-contained so that you have templates, css, logic, assets, localization etc for a particular UI component in a single place.
If you need to refer a reference architecture for large scale js development see http://boilerplatejs.org. I'm the main author of it and it demonstrates a lot of patterns that are useful in complex product development.

Categories