Overriding method in node.js - javascript

i'm looking for the best way to overrid a method in a custom module node.js.
I'm working on a custom middleware who will help me to automatically load some custom module. Like security, users etc...
But i want to be able to override some methods if i need something like a custom security hand check.
For now the only way i found is to export a function who will replace my method and expose context variables.
// CUSTOM MODULE EXAMPLE
// ========================================
var myVar = "Hello ";
var myVar2 = "!";
var method = function() {
return "world" + myVar2;
}
module.exports.loadModule = function() {
console.log(myVar + method());
};
module.exports.overrideMethod = function(customMethod) {
method = customMethod;
};
module.exports.myVar2 = myVar2;
And my main app will be like that:
// MAIN APP EXAMPLE
// ========================================
var myCustomModule = require('customModule.js');
myCustomModule.overrideMethod(function() {
return "viewer" + myCustomModule.myVar2;
});
myCustomModule.loadModule();
What do you think? Am i on the good way?
Thanks for reading.
Tom

Generally I treat any module that has mutable global state like this to be a mistake. Instead, I'd opt for creating an object with these methods and having a way to pass in overrides.
// CUSTOM MODULE EXAMPLE
// ========================================
var DEFAULT_PREFIX = "Hello ";
var DEFAULT_SUFFIX = "!";
var DEFAULT_METHOD = function() {
return "world" + DEFAULT_SUFFIX;
};
module.exports = function(options){
var method = options.method || DEFAULT_METHOD
return {
loadModule: function(){
console.log(myVar + method());
}
};
};
module.exports.DEFAULT_SUFFIX = DEFAULT_SUFFIX;
Then you can use this like this:
// MAIN APP EXAMPLE
// ========================================
var myCustomModule = require('customModule.js');
var loader = myCustomModule({
method: function() {
return "viewer" + myCustomModule.DEFAULT_SUFFIX;
}
});
loader.loadModule();

Related

How to make a custom CasperJS module with custom parameter?

FileUtil.js:
exports.a = function(pre) {
var module = {}
module.writeStringToFile = function writeStringToFile() {
casper.log(pre + " succ");
};
return module
}
main.js:
var casper = require('casper').create();
var FileUtil = require('FileUtil').a('xxx')
FileUtil.writeStringToFile() //xxx succ
That works, but what I want is var FileUtil = require('FileUtil')('xxx') instead of require('FileUtil').a('xxx').
I tried exports = function(pre) ..., but it doesn't works.
So, how to make a custom CasperJS module with custom parameter?
If you want var FileUtil = require('FileUtil')('xxx') to be your object then you need to use module.exports. It can export a single object, which can even be a function:
module.exports = function(pre) {
var module = {}
module.writeStringToFile = function writeStringToFile() {
casper.log(pre + " succ");
};
return module
}
Of course, it would be a better form to rename the inner module variable to something else.

Building a plugin architecture

I'm trying to build a simple plugin architecture that allows for a nice simple API in use. Consider the following code:
//the core library namespace
var testObj = {};
//constuctor
testObj = function() {
};
//The plugin
testObj.prototype.test = (function(){
var i = 0;
var init = function() {
alert('initialized');
}
return {
init: init,
render: function(){
return i;
}
};
}());
var p = new testObj();
//p.test.init();
p.test();
Working fiddle here: http://jsfiddle.net/8LwRL/
I want users to be able to call the init method by doing p.test(). Currently this doesn't work and anyone using the plugin would have to call p.test.init(). Is there any way that I can abstract that away so the user can call the prototype method by name and have the init run automatically?
As I already mentioned in my comment, if you want to make p.test callable, you have to return a function from the IIFE, not a (simple) object. The most straightforward approach would be to return init itself. Your code could then look like
testObj.prototype.test = (function(){
var i = 0;
var init = function() {
alert('initialized');
};
init.render = function(){
return i;
};
return init;
}());
It appears a bit odd (to me) but it would do what you want.
My corrected version:
//constuctor
var testObj = function(options) {
this.init(options);
};
//I prefer to use jQuery.extend() to extend prototype. Its look better
$.extend(testObj.prototype,{
options: {},
init: function (options) {
this.options = options;
console.log('Name on init ' + options.name );
this.options.name = 'Peter';
},
test: function () {
console.log('name on test: ' + this.options.name);
}
})
var p = new testObj({name: 'John'});
p.test();
jsfiddle

What type of pattern does this JS adhere to?

I came across code similar to this recently,
// Simplified example..
var Application =
{
MemberVar1: null,
MemberVar2: null,
Initialize: function ()
{
Application.MemberVar1 = 'Foo';
Application.MemberVar2 = 'Bar';
console.log("Initializing..");
Application.GetMemberVars();
},
GetMemberVars: function ()
{
console.log(Application.MemberVar1 + ' ' + Application.MemberVar2);
}
};
$(Application.Initialize);
What is the name of this pattern/method/style? Utilizing OOP principles without using a style I've seen before, such as prototyping. What are the benefits of this style as opposed to other popular ones?
It's a simple one-off object literal that's being created... they can contain functions... perhaps that's what threw you.
The last line merely passes the Application.Initialize function to jQuery as a $(document).ready callback function
In light of the comments below, this is what the code actually does (and how you can write it a lot shorter/easier)
$(function()
{
console.log("Initializing..");
console.log("Foo Bar");//replace this with variables you declare #top of anon. function if you want
});
As a module (you can find out more about the module pattern here):
var Application = (function()
{
var memberVar1, memberVar2,
getMemberVars = function()
{
return memberVar1 + ' ' + memberVar2;
};
return {init: function()
{
memberVar1 = 'Foo';
memberVar2 = 'Bar';
console.log('initializing...');
console.log(getMemberVars());
}};
}());
$(Application.init);
Application is now an object literal, with only 1 property (init): a function that, because it was declared within the scope of that IIFE, has access to all variables local to that scope. That's the magic of closures for you. You can easily add getters and setters for the member vars, too:
var Application = (function()
{
var memberVars = {},//turned into object literal...
getMemberVars = function(all)
{
var i;
if(typeof all === 'string' || typeof all === 'number')
{
return memberVars[all];
}
all = [];
for (i in memberVars)
{
if (memberVars.hasOwnProperty(i))
{
all.push(memberVars[i]);
}
}
return all;//or all.join(' '), as you please
},
get = function(name)
{
return typeof name === 'undefined' ? name : memberVars[name];
},
set = function(name, val)
{
memberVars[name] = val;
};
return {init: function()
{
memberVars.one = 'Foo';
memberVars.two = 'Bar';
console.log('initializing...');
console.log(getMemberVars().join(' '));
},
get: get,
set: set};//just add getter and setter here
}());
This has the same behavior as your code:
var Application = (function() {
var app = {
MemberVar1: null,
MemberVar2: null,
GetMemberVars: function() { /* ... */},
Initialize: function() {
this.MemberVar1 = 'Foo';
this.MemberVar2 = 'Bar';
console.log('Initializing..');
this.getMemberVars();
}
};
$(function() {app.Initialize();});
return app;
}());
But there's a good chance that you don't really want that Initialize function hanging around. So this would simplify it:
var Application = (function() {
var app = {
MemberVar1: null,
MemberVar2: null,
GetMemberVars: function() { /* ... */}
};
$(function() {
app.MemberVar1 = 'Foo';
app.MemberVar2 = 'Bar';
console.log('Initializing..');
app.getMemberVars();
});
return app;
}());
And unless you're actually worried about code trying to access Application.MemberVar1, etc before jQuery's document.ready event, you can simplify it further to this:
var Application = (function() {
var app = {
GetMemberVars: function() { /* ... */}
};
$(function() {
app.MemberVar1 = 'Foo';
app.MemberVar2 = 'Bar';
console.log('Initializing..');
app.getMemberVars();
});
return app;
}());
I'm assuming that defining those MemberVars took some real work, and were not simple strings as in the example. If that's not the case, then I would switch this last to
var Application = (function() {
var app = {
MemberVar1: 'Foo';
MemberVar2: 'Bar';
GetMemberVars: function() { /* ... */}
};
$(function() {
console.log('Initializing..');
app.getMemberVars();
});
return app;
}());
You don't need to use prototype if you are going to use only one instance of some object.
In this case it's pretty clear the Application object is something unique and the author didn't intend there were going to be any additional copies of Application created.
Talking about style... that capital camel case looks ugly. The common agreement is to use CapitalCamelCase only for object constructors. I personally think it's ok to use for unique objects with logic too (Application). But using it for function names and variables should be avoided.
Talking about patterns... it's close to Singleton pattern. But don't think too much about it. All those OOP patterns from Java world lose part of their appeal in JS world. Some of them disintegrate completely. Concentrate on JS ways of solving problems.

Javascript module pattern, nested functions, and sub modules

I am trying to wrap my head around javascript modules, but I'm unsure how to split up a module into further sub modules. I have read that nested functions are not really a great idea, due to performance, so how do I break up a function in a module? For example, lets say I have the following module:
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
// This is where I need to define a couple smaller functions
// should I create a new module for bigFunction? If so, should it be nested in Editor.build somehow?
}
};
})();
bigFunction is only related to Editor.build. Should I attach the smaller functions that make up bigFunction to the prototype bigFunction object? I'm not even sure if that would make sense.
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
bigFunction.smallFunction();
bigFunction.prototype.smallFunction = function(){ /*do something */ };
// not sure if this even makes sense
}
};
})();
Can someone please throw me in the right direction here? There is so much misleading information online, and would just like a definite guide on how to deal with this sort of modularization.
Thank you.
Here is a snippet I use to make names for an input:
var dynamicCounter = 0;
//custom dropdown names
var createContainerNames = function () {
function Names() {
this.id = "Tasks_" + dynamicCounter + "__ContainerId";
this.name = "Tasks[" + dynamicCounter + "].ContainerId";
this.parent = "task" + dynamicCounter + "Container";
}
Names.prototype = { constructor: Names };
return function () { return new Names(); };
} ();
And then I use it:
var createdNames = createContainerNames();
var createdId = createdNames.id;
dynamicCounter++;
var differentNames = createContainerNames();
var differentId = differentNames.id;
Another approach would be to do this:
var NameModule = function(){
//"private" namemodule variables
var priv1 = "Hello";
//"private namemodule methods
function privMethod1(){
//TODO: implement
}
//"public namemodule variables
var pub1 = "Welcome";
//"public" namemodule methods
function PubMethod(){
//TODO: pub
}
return {
pub1 : pub1,
PubMethod: PubMethod
};
and then to use it
var myPubMethod = new NameModule();
myPubMethod.PubMethod();
var pubVar = myPubMethod.pub1;
EDIT
You could also take this approach:
var mod = function(){
this.modArray = [];
};
mod.prototype = {
//private variables
modId: null,
//public method
AddToArray: function (obj) {
this.modArray.push(obj);
}
}

JavaScript Namespace

I want to create a global namespace for my application and in that namespace I want other namespaces:
E.g.
Dashboard.Ajax.Post()
Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent();
I also want to place them in seperate files:
Ajax.js
RetrieveContent.js
However I have tried using this method, however it won't work because the same variable name is being used for the namespace in 2 seperate places. Can anyone offer an alternative?
Thanks.
You just need to make sure that you don't stomp on your namespace object if it's already been created. Something like this would work:
(function() {
// private vars can go in here
Dashboard = Dashboard || {};
Dashboard.Ajax = {
Post: function() {
...
}
};
})();
And the RetrieveContent file would be defined similarly.
Here is a very good article on various "Module Patterns" in JavaScript. There is a very nice little section on how you can augment modules, or namespaces and maintain a cross-file private state. That is to say, the code in separate files will be executed sequentially and properly augment the namespace after it is executed.
I have not explored this technique thoroughly so no promises... but here is the basic idea.
dashboard.js
(function(window){
var dashboard = (function () {
var my = {},
privateVariable = 1;
function privateMethod() {
// ...
}
my.moduleProperty = 1;
my.moduleMethod = function () {
// ...
};
return my;
}());
window.Dashboard = dashboard;
})(window);
dashboard.ajax.js
var dashboard = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
// permanent access to _private, _seal, and _unseal
my.ajax = function(){
// ...
}
return my;
}(dashboard || {}));
dashboard.retrieveContent.js
var dashboard = (function (my) {
var _private = my._private = my._private || {},
_seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
},
_unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
// permanent access to _private, _seal, and _unseal
my.retrieveContent = function(){
// ...
}
return my;
}(dashboard || {}));
The Yahoo Namespace function is exactly designed for this problem.
Added:
The source of the function is available. You can copy it into your own code if you want, change the root from YAHOO to something else, etc.
There are several libraries that already offer this sort of functionality if you want to use or examine a pre-baked (that is, a tested) solution.
YUI.attribute and YUI.base
dojo.mixin
underscore.extend
jQuery.extend
goog.provide and goog.object.extend
The simplest and most bug free one to get going with is probably jQuery.extend, with the deep argument set to true. (The reason I say it is bug free is not because I think that jQuery.extend suffers from less bugs than any of the other libraries -- but because it offers a clear option to deep copy attributes from the sender to the receiver -- which most of the other libraries explicitly do not provide. This will prevent many hard-to-diagnose bugs from cropping up in your program later because you used a shallow-copy extend and now have functions executing in contexts you weren't expecting them to be executing in. (If however you are cognizant of how you will be extending your base library while designing your methods, this should not be a problem.)
With the NS object created, you should just be able to add to it from where ever. Although you may want to try var NS = NS || {}; to ensure the NS object exists and isn't overwritten.
// NS is a global variable for a namespace for the app's code
var NS = NS || {};
NS.Obj = (function() {
// Private vars and methods always available to returned object via closure
var foo; // ...
// Methods in here are public
return {
method: function() {
}
};
}());
You could do something like this...
HTML page using namespaced library:
<html>
<head>
<title>javascript namespacing</title>
<script src="dashboard.js" type="text/javascript"></script>
<script src="ajax.js" type="text/javascript"></script>
<script src="retrieve_content.js" type="text/javascript"></script>
<script type="text/javascript">
alert(Dashboard.Ajax.Post());
alert(Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent());
Dashboard.RetrieveContent.Settings.Timeout = 1500;
alert(Dashboard.RetrieveContent.Settings.Timeout);
</script>
</head>
<body>
whatever...
</body>
</html>
Dashboard.js:
(function(window, undefined){
var dashboard = {};
window.Dashboard = dashboard;
})(window);
Ajax.js:
(function(){
var ajax = {};
ajax.Post = function() { return "Posted!" };
window.Dashboard.Ajax = ajax
})();
Retrieve_Content.js:
(function(){
var retrieveContent = {};
retrieveContent.RefreshSalespersonPerformanceContent = function() {
return "content retrieved"
};
var _contentType;
var _timeout;
retrieveContent.Settings = {
"ContentType": function(contentType) { _contentType = contentType; },
"ContentType": function() { return _contentType; },
"Timeout": function(timeout) { _timeout = timeout; },
"Timeout": function() { return _timeout; }
};
window.Dashboard.RetrieveContent = retrieveContent;
})();
The Dashboard.js acts as the starting point for all namespaces under it. The rest are defined in their respective files. In the Retrieve_Content.js, I added some extra properties in there under Settings to give an idea of how to do that, if needed.
I believe the module pattern might be right up your alley. Here's a good article regarding different module patterns.
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
I highly recommend you use this technique:
https://github.com/mckoss/namespace
namespace.lookup('com.mydomain.mymodule').define(function (ns) {
var external = namespace.lookup('com.domain.external-module');
function myFunction() {
...
}
...
ns.extend({
'myFunction': myFunction,
...
});
});
I've been using this pattern for a couple of years; I wish more libraries would do the same thing; it's made it much easier for me to share code across my different projects as well.
i wrote this function to simplify creating namespaces. Mabey it will help you.
function ns(nsstr) {
var t = nsstr.split('.');
var obj = window[t[0]] = window[t[0]] || {};
for (var i = 1; i < t.length; i++) {
obj[t[i]] = obj[t[i]] || {};
obj = obj[t[i]];
}
}
ns('mynamespace.isawesome.andgreat.andstuff');
mynamespace.isawesome.andgreat.andstuff = 3;
console.log(mynamespace.isawesome.andgreat.andstuff);
bob.js can help in defining your namespaces (among others):
bob.ns.setNs('Dashboard.Ajax', {
Post: function () { /*...*/ }
});
bob.ns.setNs('Dashboard.RetrieveContent', {
RefreshSalespersonPerformanceContent: function () { /*...*/ }
});
Implementation:
namespace = function(packageName)
{
// Local variables.
var layers, layer, currentLayer, i;
// Split the given string into an array.
// Each element represents a namespace layer.
layers = packageName.split('.');
// If the top layer does not exist in the global namespace.
if (eval("typeof " + layers[0]) === 'undefined')
{
// Define the top layer in the global namesapce.
eval(layers[0] + " = {};");
}
// Assign the top layer to 'currentLayer'.
eval("currentLayer = " + layers[0] + ";");
for (i = 1; i < layers.length; ++i)
{
// A layer name.
layer = layers[i];
// If the layer does not exist under the current layer.
if (!(layer in currentLayer))
{
// Add the layer under the current layer.
currentLayer[layer] = {};
}
// Down to the next layer.
currentLayer = currentLayer[layer];
}
// Return the hash object that represents the last layer.
return currentLayer;
};
Result:
namespace('Dashboard.Ajax').Post = function() {
......
};
namespace('Dashboard.RetrieveContent').RefreshSalespersonPerformanceContent = function() {
......
};
Gist:
namespace.js

Categories

Resources