working on a script and I thought dot notation would be a good way of building methods to use later on in the grander scheme of the script.
the original system would declare functions written as
memRead();
memReadGlobal();
memWrite();
memEtc();.......
but I wanted to change this to
mem.Read();
mem.Read.Global();
Here is an example
var mem = {
Read: {
function() {
console.log('Hello World')
},
Global:
function(key) {
console.log('Goodbye World')
},
},
}
I can call mem.Global just fine, but I can't call mem.Read
I can declare mem.Read if I add another object like Local(mem.Read.Local), but I feel like writing local is redundant and would like to avoid that.
Is there a way to create a nested function like I describe above?
You can do that, but not with an object initializer expression.
var mem = {
Read() {
console.log("Hello from Read");
}
};
mem.Read.Global = function() {
console.log("Hello from Global");
};
mem.Read();
mem.Read.Global();
Related
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
I try to change some way to call methods into namespace.
Calling parent methods (I dont think its possible)
Creating and call inheritance function
Calling inside another method (mostly jquery onReady event function) (this.MyFunction() not working)
I split every namespace in files (want to keep it that way)
I try How to call function A from function B within the same namespace? but I didn't succed to split namespaces.
my fiddle sample got only 1 sub-namespace but could be more.
https://jsfiddle.net/forX/kv1w2rvc/
/**************************************************************************
// FILE Master.js
***************************************************************************/
if (!Master) var Master = {};
Master.Print= function(text){
console.log("master.Print :" + text);
$("body").append("<div>master.Print : " + text + "</div>");
}
/**************************************************************************
// FILE Master.Test1.js
***************************************************************************/
if (!Master) var Master = {};
if (!Master.Test1) Master.Test1 = {};
/**************************************************************************
* Descrition :
* Function for managing event load/documentReady
**************************************************************************/
Master.Test1.onReady = function () {
$(function () {
Master.Test1.Function1(); //try to replace because need all namespace.
try {
this.Function2(); //not working
}
catch(err) {
console.log("this.Function2 not working");
$("body").append("<div>this.Function2 not working</div>");
}
try {
this.Print("onReady"); //not working
}
catch(err) {
console.log("this.Print not working");
$("body").append("<div>this.Print not working</div>");
}
try {
Print("onReady"); //not working
}
catch(err) {
console.log("Print not working");
$("body").append("<div>Print not working</div>");
}
});
}
Master.Test1.Function1 = function () {
console.log("Function1");
$("body").append("<div>Function1</div>");
this.Function3(); //working because not inside another function
}
Master.Test1.Function2 = function () {
$("body").append("<div>Function2</div>");
console.log("Function2");
}
Master.Test1.Function3 = function () {
$("body").append("<div>Function3</div>");
console.log("Function3");
Master.Print("Function3"); //try to replace because need all namespace.
}
Master.Test1.onReady();
I use Master.Test1.Function1(); and I want to change that because Function1 is inside the same namespace.
I use Master.Print("Function3"); I dont think I can change that. the way I try to use it, it's more an inheritance function. but I dont know if theres a way to do that?
Maybe I should change the my namespace methode? maybe prototype will do what I want?
You can capture the this in a variable because this inside $(function() {}) will point to document object. The below will work provided you never change the calling context of onReady -- i.e. it is always called on the Test1 object and not called on other context:
Master.Test1.onReady = function () {
var self = this;
$(function () {
self.Function1();
// ..
});
}
To access Print you have to reference using the Master object like: Master.Print() as it won't be available in the Test1 object
this is document within .ready() or jQuery() alias for .ready() where function(){} is parameter $(function() {}). this at this.Function2() will reference document.
"Objects" in javascript are not built the same way as in most object-oriented languages. Essentially, what you are building is a hierarchy of static methods that have no real internal state in-and-of themselves. Therefore, when one of the defined methods is invoked, the context (or state) of that method depends on what object invoked the method.
If you want to have any internal context, you will need to create an "instance" of an "object prototype". At that point, you can use "this.otherFunction" within your other functions. Here is a small example:
var MyObject = function() {};
MyObject.functionOne = function() {
console.log("Function 1");
this.functionTwo();
};
MyObject.functionTwo = function() {
console.log("Function 2");
};
var instanceOne = new MyObject();
instanceOne.functionOne();
You might get some more information about object definition here
I am trying to build a lib and I need to call functions dynamically depending on the variables I have in parameter like this
strategies = min
function dispatchRuleToStrategy(strategies)
{
$.each(strategies, function(index, value) {
strategy = "strategy_" + value;
});
}
function strategy_min()
{
// do something
}
How can I call the function strategy_min() from dispatchRuleToStrategy()?
I've been trying a couple of things none of which are working.
Thanks for your help
Use an Object to create a dictionary of your functions e.g. lib
var lib = {
'strategy_min': strategy_min
};
then you can invoke via the key in this dictionary Object
lib['strategy_min']();
If you've named all your functions and you don't want to re-type the names over and over, you could
var lib = {};
function addToLib(fn) {
lib[fn.name] = fn;
}
// then
addToLib(strategy_min);
// or
[strategy_min].forEach(addToLib);
Put them in an object and use the property name:
var strategy_table = {
min: function() {
// do something
},
max: function() {
// do something else
},
...
};
Then you can access them as strategy_table[value]:
$.each(strategies, function(index, value) {
strategy_table[value]();
});
Others have already suggested to create a wrapper object for the functions, however, if your strategy_min() function is in the global scope, you can access it directly:
window['strategy_' + value]();
window in browsers refers to the global object. The bracket notation is used to access properties whose keys are dynamically generated. This way you are accessing the function, which is a property of the global object, i.e. window, and calling it using the parentheses.
Finally I found the real problem. I was in a jquery document ready which is a closure. I did not knew what closures were before today.
Thanks all for your help
You can use eval() function in the following manner
$.each(strategies, function(index, value) {
strategy = "strategy_" + value;
eval(strategy+"()");
});
Given a javascript object like this:
var myThing = {};
Object.defineProperty(myThing, 'gen', {
'get' : function() {
// access caller name here, so I can return cool/neat stuff
}
});
I want to be able to get children of myThing.gen, but know what is being asked for in the getter.
for example:
var coolThing = myThing.gen.oh.cool;
var neatThing = myThing.gen.oh.neat;
I want the "oh.cool" or "oh.neat" part in getter, so I can make decisions based on this, and return something specific to it. I am ok with solution not working in IE, or old browsers, as it is primarily for node.
The actual purpose of this is so that I can request myThing.gen.oh.neat and have the myThing.gen getter resolve to require('./oh/neat.js') and return it.
Since require cache's, this is an efficient way to dynamically load modular functionality, and have a tidy interface (rather than just dynamically building the require where needed) without having to know the structure ahead of time.
If there is no introspection-of-name function that can get this for me, I could just do something less elegant, like this:
myThing.gen = function(name){
return require('./' + name.replace('.', '/') + '.js');
}
and do this:
neatThing = myThing.gen('oh.neat');
I don't like this syntax as much, though. I looked at chai's dynamic expect(var).to.not.be.empty stuff, but couldn't figure out how to do it completely dynamically. Maybe there is not a way.
without actually solving the problem of dynamically discovering the caller, I can do this:
var myThing = {};
Object.defineProperty(myThing, 'gen', {
'get' : function() {
return {
'oh':{
'cool': require('./oh/cool.js'),
'neat': require('./oh/neat.js')
}
};
}
});
Is there a way to do this dynamically?
You can't see what the property gen will be used for in the future, so you would need to return an object with properties that react to what the object is used for when it actually happens:
var myThing = {};
Object.defineProperty(myThing, 'gen', {
'get' : function() {
var no = {};
Object.defineProperty(no, 'cool', {
get: function(){ alert('cool'); }
});
Object.defineProperty(no, 'neat', {
get: function(){ alert('neat'); }
});
return { oh: no };
}
});
Demo: http://jsfiddle.net/UjpGZ/1/
I have a scenario in which i need to override sample.A in sample.B
and when i click i will call a function from which i need to call sample.A.Test() which need to internally call the overridden function(Test) in sample.B and execute only this function. is it possible ?
My peers told that java script will call the subclass function by default and get executed, is it true?
The above scenario
sample.A = (function () {
return {
Test: function(){
console.debug('Test in Super class');
},
}
sample.B = (function () {
return {
Test: function(){
console.debug('Test in Sub class');
},
}
can this behavior be achieved through java script or jquery?
To enable 'inheritance' in JavaScript, you at the very least need to add some utility methods.
For instance:
function inheritMethods(fromA, intoB) {
for (x in fromB) {
if (typeof x === 'function') {
intoB[x] = fromA[x];
}
}
}
or something the like ...
But since 'inheritance' in the classical OO sense is not native to JavaScript there are various ways about emulating this. There is a nice discussion in 'JavaScript Patterns' under 'Code Reuse' on this, if you can get hold of the book.