Function Composition: Augmenting an existing function with additional function in Javascript - javascript

I import a library with a function and would like to replace that function with a function that takes the original function as an argument together with an additional function.
The original function might be logThis:
function logThis() {console.log('this'));
I can create a new function which executes logThis and then logs 'that';
function logThisThenThat() {
logThis();
console.log('that');
}
I would like to replace logThis with a new function which executes the original function and thereafter another function? Is this possible with function composition or will I have to create a new function with a different name which is made up of the original function and additional functions.
Something along the lines of:
logThis = compose(logThis, logThat);

You can create a function like this.
function logThis() {
console.log("this");
}
function logThat() {
console.log("that");
}
let compose = (...func) => ()=> {
let functions = func;
functions.forEach((fn) => fn());
}
logThis = compose(logThis, logThat);
logThis();
Adding (...func) as parameters, you can execute 3, 4 any amount of functions you like/need.
Note: Edit the snippet to match the question. The selected answer by #mark-meyer is correct.

You can override the existing function with a new one.
Keep a copy of the original like this...
_logThis = logThis;
...and then make your new version call the original one...
function logThis() {
_logThis();
// your other function call or new code goes here
}
This isn't a particularly good idea though, since that will modify what happens for every single existing call to that method. This needs to be handled with care.
Also, scope is a big factor here. This is a basic example of what you're trying to do.

If you pass logThis() into your compose() function, you will hold a reference to it in the closure, so it will live on when you make a new logThis(). The name isn't really that important so long as you rename in an order that lets you get the reference to the old logThis() before you point the name at a new function. For example, the right side of logThis = compose(logThis, logThat) runs before the name assignment below, so you capture the function reference before reassigning the name:
function logThis() {console.log('this')};
function logThat() {console.log('that')};
let compose = (f1, f2) => () => {
f1()
f2()
}
logThis = compose(logThis, logThat)
logThis()

Related

Detect the caller and called it

I want to recognize the calling function and one function call it that
The following example illustrates this issue
<script>
var func = (function () {
var check = function (value) {
//detect caller function
var that = arguments.callee.caller;
//I want
//if Buttom One click --> call print in func1
//if Buttom Two click --> call print in func2
};
return {
check:check
}
})();
var func1 = (function () {
var start = function () {
func.check(10);
};
var print = function (value) {
alert(value);
}
return {
start: start,
print: print
}
})();
var func2 ...
</script>
<button id="One" onclick="func1.start()">One</button>
<button id="Two" onclick="func2.start()">Two</button>
Do you have a solution?
Many thanks!
Putting aside the fact that arguments.callee and Function.caller are both non-standard, the reason why it doesn't work is that you are confusing properties with local variables, all that mixed in with closures.
var func1 = (function () {
// ...
})();
This creates a function, runs it and saves the result in func1. Since the return statement of your closure is return { start: start }, at the end of this section of code func1 will contain an object which as a method called start.
When you use var, you're only creating a variable which exists inside that function. Outside of the function, it is no longer accessible. You did store the start function in the returned object, but you never returned print so it doesn't exist anymore.
Instead of going line by line and trying to explain all what is wrong, I'll ask you this: what you were actually trying to do? Don't ask us about your attempted solution which didn't work, but about what the code should do.
I suggest you look at these answers I wrote if you need further explanations on closures and scope.
Understanding public/private instance variables
Do the different methods of creating classes in Javascript have names and what are they?

What is the correct way of calling an internal function using the module pattern in Javascript

I am new to Javascript and am still getting my head round the various ways of creating objects i.e constructor+new, prototypal, functional & parts.
I have created what I think is an object factory using the module pattern and want to know what the correct method of calling an internal method would be. Is it via this or function name.
Here is my module:
function chart() {
function my() {
// generate chart here, using `width` and `height`
}
my.sayHi = function(){
console.log('hi');
my.sayBye();
};
my.sayBye = function(){
console.log('Bye');
};
return my;
}
var test = chart();
test.sayHi();
You can see that the first function calls the second using my.sayBye() or is it better to use this.sayBye(). Both produce the same result and run without error.
The module pattern allows you to dispense with the 'this' variable if you want to. I would probably rewrite the above code to look like this and then the question becomes moot.
function chart() {
var hiCount = 0;
function sayHi(){
console.log('hi');
hiCount++;
sayBye();
};
function sayBye(){
console.log('Bye');
};
return {
sayHi : sayHi,
sayBye: sayBye
};
}
var test = chart();
test.sayHi();
In the above code all is defined within the function chart. As JavaScript's scope is at the function level every time the chart function is called a new set of functions will be defined. And a new set of variables can also be defined that are private to the function as they are defined in the function and are not accessible from outside. I added hiCount as an example of how you could do this. The Module pattern allows privacy in JavaScript. It eats more memory than the prototype pattern though as each time a function is declared it is not shared between other instances of the same class. That is the price you have to pay in Javascript to have class variables that are private. I willingly pay it. Removing 'this' from my code makes it easier to understand and less likely that I will fall into problems of misplaced scope.
Using "this" is better approach because you would be able to bind the function directly to the parent function object.And you dont need to return anything from the function.
where as in your case you are explicitly returning another function
Here is the use of "this" approach
function chart() {
this.sayHi = function(){
console.log('hi');
}
}
var test = new chart();
test.sayHi();
Using this approach you would be able to call anything in the prototype of function "chart"
Eg
chart.prototype.hello = function(){
console.log('hello')
}
So you would be able to call the hello function from the same object(test)

call a js function based on the argument passed

I'm trying to call a js function within another one, but use the argument to specify the function. ie depending on the argument passed, it will call a different function
function toggle(n){
if (sessionStorage['toggle'+n]== 0){
check+n();
}
else
}
So, for example, if the argument 'Balloons' was passed as n, then it will call the function checkBalloons(). "check+n();" is not currently working here. Sorry for my lack of simple js syntax!
If the function is defined in the global scope (browser) you can do:
window["check"+n]();
or some tenants like Node.js you would access it from global object.
global["check"+n]();
if it is a part of some other object then you would do the same.
obj["check"+n]();
Functions and properties defined on an object can be accessed using [] convention as well. i.e obj["propFuncName"] will give you reference to it, so in case of methods you add () to invoke it.
If the function is global, you would do this:
window["check" + n]();
or, you could put your function in an object like so:
myNamespace = {};
myNamespace.checkSomething = function(){ /* ... */ }
// call it like this:
myNamespace["check" + n]();
The answers thus far are correct, but lack explanation.
In JavaScript, you cannot call a function by name when that name is a string. What you can do is retrieve a value from an object by name, and if that value happens to be a function, you can then call it. For example:
var myObject = {};
myObject.myFunction = function() { alert('test!'); };
// Get the property on `myObject` called `myFunction`
var theFunctionLookup = myObject['myFunction'];
// Since that property was a function, you can call it!
theFunctionLookup();
In the browser, functions that are defined in the global scope are attached to the window object. For example, this works:
function myFunction() { alert('test'); }
var theFunctionLookup = window['myFunction'];
theFunctionLookup();
You can shorten the last two lines into one:
function myFunction() { alert('test'); }
// Look up and call the function in one line.
window['myFunction']();
For the same reasons, you can use a dynamically-calculated string to look up functions.
function checkBalloon() {
alert('checking balloon');
}
function toggle(n){
if (sessionStorage['toggle'+n]== 0){
window['check' + n]();
check+n();
}
}
toggle('Balloon');
if you do this way:
if (sessionStorage['toggle'+n]== 0){
window["check" + n]();
}
will work

How to execute a method passed as parameter to function

I want to write my own function in JavaScript which takes a callback method as a parameter and executes it after the completion, I don't know how to invoke a method in my method which is passed as an argument. Like Reflection.
example code
function myfunction(param1, callbackfunction)
{
//do processing here
//how to invoke callbackfunction at this point?
}
//this is the function call to myfunction
myfunction("hello", function(){
//call back method implementation here
});
You can just call it as a normal function:
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction();
}
The only extra thing is to mention context. If you want to be able to use the this keyword within your callback, you'll have to assign it. This is frequently desirable behaviour. For instance:
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction.call(param1);
}
In the callback, you can now access param1 as this. See Function.call.
I too came into same scenario where I have to call the function sent as parameter to another function.
I Tried
mainfunction('callThisFunction');
First Approach
function mainFuntion(functionName)
{
functionName();
}
But ends up in errors. So I tried
Second Approach
functionName.call().
Still no use. So I tried
Third Approach
this[functionName]();
which worked like a champ. So This is to just add one more way of calling. May be there may be problem with my First and Second approaches, but instead googling more and spending time I went for Third Approach.
function myfunction(param1, callbackfunction)
{
//do processing here
callbackfunction(); // or if you want scoped call, callbackfunction.call(scope)
}
object[functionName]();
object: refers to the name of the object.
functionName: is a variable whose value we will use to call a function.
by putting the variable used to refer to the function name inside the [] and the () outside the bracket we can dynamically call the object's function using the variable. Dot notation does not work because it thinks that 'functionName' is the actual name of the function and not the value that 'functionName' holds. This drove me crazy for a little bit, until I came across this site. I am glad stackoverflow.com exists <3
All the examples here seem to show how to declare it, but not how to use it. I think that's also why #Kiran had so many issues.
The trick is to declare the function which uses a callback:
function doThisFirst(someParameter, myCallbackFunction) {
// Do stuff first
alert('Doing stuff...');
// Now call the function passed in
myCallbackFunction(someParameter);
}
The someParameter bit can be omitted if not required.
You can then use the callback as follows:
doThisFirst(1, myOtherFunction1);
doThisFirst(2, myOtherFunction2);
function myOtherFunction1(inputParam) {
alert('myOtherFunction1: ' + inputParam);
}
function myOtherFunction2(inputParam) {
alert('myOtherFunction2: ' + inputParam);
}
Note how the callback function is passed in and declared without quotes or brackets.
If you use doThisFirst(1, 'myOtherFunction1'); it will fail.
If you use doThisFirst(1, myOtherFunction3()); (I know there's no parameter input in this case) then it will call myOtherFunction3 first so you get unintended side effects.
Another way is to declare your function as anonymous function and save it in a variable:
var aFunction = function () {
};
After that you can pass aFunction as argument myfunction and call it normally.
function myfunction(callbackfunction) {
callbackfunction();
}
myfunction(aFunction);
However, as other answers have pointed out, is not necessary, since you can directly use the function name. I will keep the answer as is, because of the discussion that follows in the comments.
I will do something like this
var callbackfunction = function(param1, param2){
console.log(param1 + ' ' + param2)
}
myfunction = function(_function, _params){
_function(_params['firstParam'], _params['secondParam']);
}
Into the main code block, It is possible pass parameters
myfunction(callbackfunction, {firstParam: 'hello', secondParam: 'good bye'});
callbackfunction = () => {}
callbackfunction2(){
}
function myfunction1(callbackfunction) {
callbackfunction();
}
//Exe
myfunction1(callbackfunction);
myfunction1(callbackfunction2.bind(this));
Super basic implementation for my use case based on some excellent answers and resources above:
/** Returns the name of type member in a type-safe manner. **(UNTESTED)** e.g.:
*
* ```typescript
* nameof<Apple>(apple => apple.colour); // Returns 'colour'
* nameof<Apple>(x => x.colour); // Returns 'colour'
* ```
*/
export function nameof<T>(func?: (obj: T) => any): string {
const lambda = ' => ';
const funcStr = func.toString();
const indexOfLambda = funcStr.indexOf(lambda);
const member = funcStr.replace(funcStr.substring(0, indexOfLambda) + '.', '').replace(funcStr.substring(0, indexOfLambda) + lambda, '');
return member;
}

call a specific javascript function when multiple same name function are in memory

I need to call specific js function. The problem is many time runtime situation can come where another js file may contain same name function. But i need to be specific that which function i am suppose to call.
Function overloading is not my solution.
Thanks and regards,
Tanmay
you're going to have to do some reorganization of your resources and use namespacing where you can.
if you have a method named saySomething defined twice, you would move one of them to an object (whichever suits your needs better).
var myNS = new (function() {
this.saySomething = function() {
alert('hello!');
};
})();
and the other defintion can be moved into a different object or even left alone.
function saySomething() {
alert('derp!');
}
you can now call the saySomething method like
saySomething(); // derp!
myNS.saySomething(); // hello!
edit: since it was brought up in comments, this
var myNS = {
saySomething: function() {
alert('hello!');
}
};
is equivalent to the first code block, in simpler form (if i'm remembering correctly).
At least in firefox, when you have two functions with the same name, the second will overwrite the first one.
So, you can't call the first one.
Try it:
function a() {alert(1);}
function a() {alert(2);}
a(); // alerts '2'
See in jsfiddle.
In javascript, similarly named functions automatically override previous function defined with the exact same name.
Let's say your page includes 1.js and 2.js and both of them define the same function, for example say, display(). In this case, based on which js file is included the last, the definition of 'display()' in that file will override all other prior definitions.
I use function scope to limit the scope of variables and functions
Here is an example:
// existing function in JavaScript
function one() {
console.log('one');
}
one(); // outputs one
// inserting new JavaScript
(function() { // anonymous function wrapper
'use strict'; // ECMAScript-5
function one() {
console.log('two');
}
one(); // outputs two
})(); // end of anonymous function
one(); // outputs one
I hope that helps
:)

Categories

Resources