I'm using the following format to avoid possible naming conflicts.
My main aim is to keep the parts of the program in different files during development and then later combine it
Editor is the
main.js
Editor=function(){
this.manage=function(){
}
}
var editor= new Editor;
a.js
Editor.prototype.A=function(){
this.afunct=function(){
}
}
b.js
Editor.prototype.B=function(){
var this.var1;
var this.var2;
this.bfunct=function(){
//call afunct() here
}
}
A is a set of functions that does some testing,modification etc.
afunct is a tester function which needs to be used in all the other files.
B is supposed to act as a data package and new instances of it will be created to pass around.
How will I call afunct inside bfunct?
Please help me understand how I can do this. Thank You in advance.
PS. I'm kind of a newbie in Javascript and please pardon any flaw in my logic.
It's obscure, but this might do it:
(function() {
var Editor = function() {
};
Editor.prototype = {
A: {
afunct: function() {
// Other functionality here.
}
},
B: {
bfunct: function() {
Editor.prototype.A.afunct.call(this);
}
}
};
window.Editor = Editor;
})();
var editor = new Editor();
editor.B.bfunct();
From inside B this should work
Editor.A.apply(this)
Try this from inside Editor.prototype.B:
Editor.prototype.B=function(){
var this.var1;
var this.var2;
var self = this;
this.bfunct=function(){
//call afunct() here
self.prototype.B.afunct();
}
}
Related
I'm developing a NodeJS application and use Mocha for unit testing.
Let's say i have two very similar test suits.
In fact those are tests for two classes which
implement the same interface.
For example:
suit_a.js
var A = require('./a');
describe(function () {
var instance;
beforeEach(function () {
instance = new A();
});
it(function () {
assert(instance.getSomeValue() === 1);
});
});
suit_b.js
var B = require('./b');
describe(function () {
var instance;
beforeEach(function () {
instance = new B({option: "option-value"});
});
it(function () {
assert(instance.getSomeValue() === 1);
});
});
Is there a way to remove code repetition? Is there a way to have two
different test suits, using same assertion code, but with different configuration
or something like that?
The only idea I have right now is to use some kind of source code generation,
but I would like to avoid that if possible.
Move the inner function to an extra file and require it.
In your case you need new A() and new B(...) extra, so either make them available outside or include them as a parameter to the require-result:
var t = require('innerTestGen');
var t1 = t.create(new A())
describe(t1);
var t2 = t.create(new B(...))
describe(t2);
Hope that helps?
I have a few questions about Best Practises using javascript in external files and namespacing.
Let's have a namespace MyCompany, global configuration stuff, code for individual pages and maybe some "API"s.
var MyCompany = {};
Global configuration in HTML
MyCompany.root = "/";
Which approach is better
First
MyCompany.Page = {};
(function(ns} {
ns.init = function() {
var root = MyCompany.root;
ajax(root+"somepage.html");
};
}(MyCompany.Page.Home = MyCompany.Page.Home || {});
and in html use
<script>
$( function() {
MyCompany.Page.Home.init();
});
</script>
Second (Page as an Class and its instance)
MyCompany.Page.Home = function() {
var root = MyCompany.root;
this.init = function() {
ajax(root + "somepage.html");
};
};
in html
<script>
var page = new MyCompany.Page.Home();
$( function() {
page.init();
});
</script>
Submodules and Mixing API with Page javascript
If our Homepage has some reviews.
MyCompany.Page.Home.Reviews = function() {
this.init = function() {
load_stuff();
}
};
And now inside Page init use
MyCompany.Home.Page = function(data) {
var reviews = new MyCompany.Home.Page.Reviews();
this.init = function() {
reviews.init();
};
};
Could that cause troubles?
It's obvious that Reviews extends MyCompany.Home.Page, but MyCompany.Home.Page requires Reviews.
It shouldn't cause troubles if instance on MyCompany.Home.Page is created after MyCompany.Home.Page.Reviews are loaded, right? Because Reviews in fact will extend the function object, is that right?
I guess this depends on answer to first question.
It also could be
(function(ns) {
ns.init = function() { MyCompany.Page.Home.Reviews.init(); };
})(MyCompany.Page.Home = MyCompany.Page.Home || {} );
(function(ns) {
ns.init = function() { load_stuff(); };
})(MyCompany.Page.Home.Reviews = MyCompany.Page.Home.Reviews || {});
Also should I somehow separate API of Page javascript?
Such as
MyCompany.APIS.Maps = function(location) {
/* Private variables */
var _location = location;
/* Private functions */
function search_address(address) { .. do search .. }
/* Public interface */
this.search = search_address;
do some initialization ...
};
I'd be glad if anyone reads it all to leave some comment.
Thank you in advance.
Which approach is better? Revealing singleton module (first) or a constructor function/class and its instance (second)?
Depends on your use case. If you don't expect multiple page objects to exist at once (and you hardly seem to), the singleton (with an init function) is really fine. Everything else could be considered wrong or at least overkill.
Same thing holds true for your MyCompany.Page.Home.Reviews (or MyCompany.Home.Page.Reviews?) class module, of which you seem to need only one instance.
It shouldn't cause troubles if instance on MyCompany.Home.Page is created after MyCompany.Home.Page.Reviews are loaded, right? Because Reviews in fact will extend the function object, is that right?
Yes.
(function(ns) {
ns.init = function() { MyCompany.Page.Home.Reviews.init(); };
})(MyCompany.Page.Home = MyCompany.Page.Home || {} );
If you have that ns shortcut available, you should use it:
(function(ns) {
ns.init = function() { ns.Reviews.init(); };
})(MyCompany.Page.Home = MyCompany.Page.Home || {} );
Also should I somehow separate API of Page javascript?
For development: Yes, in every case. Each module should have its own file. When deploying, you might concatenate them together for faster loading, but that's a different question.
I have and external JS scripts file with all my objects in that runs once the document is ready something like this...
jQuery(function($) {
var Main = {
run: function () {
myFunction.setup();
}
}
var myFunction = {
setup: function() {
//Do some stuff here
}
}
Main.run();
});
I want to be able to run myFunction.setup() only if im on a certain page though otherwise I get errors if that method is looking for elements on the page that don't exist e.g a slideshow, menus etc.
At the moment I have got round this by checking if the element exists with .length and if it does then running the rest of the method but I was wondering if there was a nicer way? Maybe like if it was possible to send variables to the scripts file when it loads based on the page im on so it knows what to methods run?
Any help would be really appreciated.
Thanks
Giles
Paul Irish has a great way of doing exactly this, using ID and classes from the body tag to execute certain blocks of code:
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
This kind of thing might help:
Page specific
var page_config = {
setup_allowed: true
// ... more config
};
Generic
var Main,
myFunction;
(function ($, _config) {
myFunction = (function () {
var _public = {};
if (_config.setup_allowed === true) {
_public.setup = function () {
};
}
return _public;
})();
Main = (function () {
var _public = {};
if (typeof myFunction.setup !== "undefined") {
_public.run = function () {
myFunction.setup();
};
// Run it as we had Main.run() before
_public.run();
}
return _public;
})();
})(jQuery, page_config);
This way Main.run() and myFunction.setup() are only available if specified in page_config.
Here's a working example you can have a play with. This may be a bit verbose for your particular requirement but hopefully it'll help in some way :-)
What is the equivalent code of window["functionName"](arguments) in NodeJS server-side?
If you need such a capability within a module, one hack is to store such module functions in variables within the module and then call them by accessing them from the module object properties. Example:
var x = { }; // better would be to have module create an object
x.f1 = function()
{
console.log('Call me as a string!');
}
Now, within the module, you can call it using the value from a string:
var funcstr = "f1";
x[funcstr]();
I am learning the ropes with Node myself, the above is probably all sorts of wrong :-). Perhaps a marginally better way to write this example would be (for the module m.js):
module.exports =
{
f1: function() { console.log("Call me from a string!"); },
f2: function(str1) { this[str1](); }
}
Now you can:
var m = require('m.js');
m.f2('f1');
Or even just:
var m = require('m.js');
m['f1']();
FWIW!
you're looking for global
Note, however, that in modules nothing is ever exposed to this level
1) If methods are in same js file
define all methods as properties of Handler:
var Handler={};
Handler.application_run = function (name) {
console.log(name)
}
Now call it like this
var somefunc = "application_run";
Handler[somefunc]('jerry codes');
Output: jerry codes
2) If you want to keep methods in a different js file
// Handler.js
module.exports={
application_run: function (name) {
console.log(name)
}
}
Use method defined in Handler.js in different.js:
// different.js
var methods = require('./Handler.js') // path to Handler.js
methods['application_run']('jerry codes')
Output: jerry codes
If you want to call a class level function using this then following is the solution and it worked for me
class Hello {
sayHello(name) {
console.log("Hello " + name)
}
callVariableMethod() {
let method_name = 'sayHello'
this[`${method_name}`]("Zeal Nagar!")
}
}
If You need it in module scope, You can use something like this
var module = require('moduleName');
module['functionName'](arguments);
Honestly, looking at all these answers they seem a bit too much work. I was playing around to look for other ways around this. You can use the eval() command to print a variable as text then call it as a function
I.e
let commands = ['add', 'remove', 'test'];
for (i in commands) {
if (commands[i] == command) {
var c = "proxy_"+command;
eval(c)(proxy);
}
}
eval(string)(arg1, arg2);
This example script would execute the function proxy_test(proxy)
You know, the OP's code inspired me to try this:
global.test = function(inVal){
console.log(inVal);
}
global['test']('3 is the value')
But now that I think about it, it's no better than #Ravi' s answer.
I use this for node, see if this approach works for you
var _ = require('lodash');
var fnA1 = require('functions/fnA1');
var fnA2 = require('functions/fnA2');
module.exports = {
run: function(fnName, options, callback) {
'use strict';
var nameSpace = fnName.toString().split('.');
// if function name contains namespace, resolve that first before calling
if (nameSpace.length > 1) {
var resolvedFnName = this;
_.forEach(nameSpace, function(name){
resolvedFnName = resolvedFnName[name];
});
resolvedFnName(options, callback);
} else {
this[fnName](options, callback);
}
},
fnA1: fnA1,
fnA2: fnA2
};
call this like
importVariable.run('fnA1.subfunction', data, function(err, result){
if (err) {return callback(err);}
return callback(null, result);
});
That is not specific to the window object. In JavaScript any property of the object can be accessed this way. For example,
var test = {
prop1 : true
};
console.log(test.prop1); // true
console.log(test["prop1"]); // also true
Read more here : https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects
Let's say I have a javascript object...
app.dooDad = {}
(function (O) {
O.magicStuff = function() {
alert("LOL!");
}
...other methods...
})(app.doodad)
Now let's say I make a deep copy of this object...
app.specialDooDad = jQuery.extend(true, {}, app.dooDad);
(function (O) {
O.magicStuff = function() {
alert("LOL!");
alert("Cats!");
}
})(app.doodad)
I am wondering: Is there a better way to do this? That is, is there a better way to to extend the method magicStuff with additional commands in specialDooDad, without rewriting it?
thanks (in advance) for your help.
Correct me if I'm wrong, but I believe you can do something like this in Javascript:
app.specialDooDad = jQuery.extend(true, {}, app.dooDad);
(function (O) {
O.oldMagicStuff = O.magicStuff;
O.magicStuff = function() {
//Additional stuff you want to do
alert("Cats!");
O.oldMagicStuff();
}
})(app.doodad)
That only works well if you are just adding on an additional thing or two, either before or after the "original" function would run. If you need to add things into the middle, I believe you just have to rewrite the function.
I'm assuming you want to do this to maintain backward compatibility with an existing codebase (such as an open source library)?
function DooDad() {
this.magicStuff = function() {
alert("LOL!");
}
}
app.dooDad = new ConstructorA();
function SpecialDooDad() {
var o = new DooDad;
this.magicStuff = function() {
o.magicStuff.apply(this, arguments);
alert("Cats!");
}
}
app.specialDooDad = new SpecialDooDad;
I prefer this way of extending. It's more functional. You create new objects through composition and extension.