how to call a function inside another function - javascript

I'm trying to call a function inside another function in javascript, actually trying to call populateCurrencies() inside startApp(). What am I doing wrong?
const startApp = () => {
const populateCurrencies = ();
function populateCurrencies() {
alert(return this.option.value + " " + this.option.textContent);
}
const startApp = () {};

You are using a invalid syntax.
You declare functions like this (with arrow function expression).
const myFunc = () => {
// Code to run here...
}
And you call your function like this.
myFunc();
Not const myFunc = () {}; like it is in your example.
Also, const is a constant, you can't have multiple constants with the same name, so that's an error as well. And if you want to reassign values to a variable you have to use let instead. But that's beside the point since you won't need those extra variable declarations that you have now when you call the functions.

Related

How can I "recursively" stringify a javascript function which calls other scoped functions?

Because javascript functions are not serializable, in order to pass them into new contexts sometimes (albeit rarely) it can be useful to stringify them then re-evaluate them later like:
const foo = () => { // do something }
const fooText = foo.toString()
// later... in new context & scope
const fooFunc = new Function(' return (' + fooText + ').apply(null, arguments)')
fooFunc() // works!
However, if foo references another function bar, the scope is not stringified, so if bar is not defined in the new context, the evaluated foo function will throw an error when called.
I'm wondering if there is a way to stringify a function recursively?
That is, not only stringifying the parent function, but also stringifying the contents of the child functions called from the parent.
For Example:
let bar = () => { alert(1) }
let foo = () => { bar() }
// what toString does
let fooString = foo.toString()
console.log(fooString) // "() => { bar() }"
// what we want
let recursiveFooString = foo.recursiveToString()
console.log(recursiveFooString) // "() => { alert(1) }"
Let me know if you have any ideas on how to accomplish something like a "recursiveToString"
The only good way to do this is to start from a parent scope that encloses all functions foo eventually references. For example, with your foo and bar, if you want to pass foo into another context such that bar is callable as well, pass a function that declares both foo and bar, and returns foo. For example:
const makeFoo = () => {
let bar = () => { alert(1) }
let foo = () => { bar() }
return foo;
};
const makeFooStr = makeFoo.toString();
// ...
const makeFooFunc = new Function(' return (' + makeFooStr + ').apply(null, arguments)');
const foo = makeFooFunc();
foo();
Implementing this sort of thing well does require premeditated design like above (unfortunately). You can't really include all ancestor LexicalEnvironments (the internal map of variable names to values in a given scope) when stringifying.
I'm wondering if there is a way to stringify a function recursively?
I think we can fairly simply demonstrate that this is impossible in general.
Let's think about these two function
const greet = (greeting) => (name) => `${greeting} ${name}`
const sayHi = greet ('Hi')
sayHi ('Jane') //=> "Hi Jane"
While with your foo and bar example, we could possibly imagine something that examined the body of the function and used everything available in the current scope to do your extended stringify function based on parsing the function and knowing what local variables are actually used. (I'm guessing that this would be impossible too, for reasons related to Rice's Theorem, but we can certainly imagine it.)
But here, note that
sayHi.toString() //=> "(name) => `${greeting} ${name}`"
and so sayHi depends on a free variable that's not stored in our current scope, namely, greeting. We simply have not stored the "Hi" used to create that function anywhere except in the closure scope of sayHi, which is not exposed anywhere.
So even this simple function could not be reliably serialized; there seems little hope for anything more complex.
What I ended up rolling with was inspired by #CertainPerformance's answer.
The trick is to build a function which defines all the child callee functions. Then you have everything you need to stringify the parent function.
Note: to allow for imported callee functions from other files, I decided to programmatically build a string with the callee definitions rather than defining them originally in the same scope.
The code:
// original function definitions (could be in another file)
let bar = () => { alert(1) }
let foo = () => { bar() }
const allCallees = [ bar, foo ]
// build string of callee definitions
const calleeDefinitions = allCallees.reduce(
(definitionsString, callee) => {
return `${definitionsString} \n const ${callee.name} = ${callee.toString()};`;
},
"",
);
// wrap the definitions in a function that calls foo
const fooString = `() => { ${calleeDefinitions} \n return foo(); \n }`;
console.log(fooString);
/**
* fooString looks like this:
* `() => {
* const bar = () => { alert(1) };
* const foo = () => { bar() };
* return foo();
* }`
**/
// in new context & scope
const evaluatedFoo = new Function(' return (' + fooString + ').apply(null, arguments)');
// works as expected
evaluatedFoo();

Call a function starting only with the function name as a string (ES6 syntax)

I'm doing a weird thing where I get the name of a function, and call the function with that name, like this:
function myFunc(){
//do somethng
};
var myFuncName = 'myFunc';
window[myFuncName](); // Expected result.
...which works, but now I've defined the func using ES6 const naming, window[myFuncName] is undefined:
const myFunc = () => {
//do somethng
};
var myFuncName = 'myFunc';
window[myFuncName](); // window[myFuncName] is not a function.
Does anyone know how to call an ES6 function when you have only it's name as a string? I'm working in a browser Web Extension but think this is a general JavaScript problem. Thanks!
It'd only be possible with eval, which shouldn't be used:
eval(myFuncName + '()');
Instead, change your code so that the function is put onto an object (even if it's not the window), then use ordinary bracket notation to look up the property value (just like you're doing with window, except with fns instead), and call the retrieved function:
const fns = {
myFunc() {
console.log('do something');
}
};
const myFuncName = 'myFunc';
fns[myFuncName]();
If you want to more closely imitate const for the property on the object, use Object.defineProperty to make sure the function property can't be deleted nor reassigned, via configurable: false:
'use strict';
const fns = {};
Object.defineProperty(fns, 'myFunc', {
configurable: false,
value: () => {
console.log('do something');
}
});
const myFuncName = 'myFunc';
fns[myFuncName]();
// can't reassign property:
fns.myFunc = 'foo';

Node js: Call internal function in module.exports

I am writing a module that needs to call internal functions within the module and make use of variables in the constructor. To call these functions internally I could either use the variable mycode or use the keyword this. However using mycode means using a global variable and this can be overwritten by parts of my functions. This is a simplified model of my module's structure:
// app.js
const MyCode = require('mycode.js');
var mycode = new MyCode();
mycode.function1($(html));
// mycode.js
module.exports = class {
constructor() {
this.alertUrl = true;
}
function1(html) {
html.find('a').each(function () {
var url = $(this).attr('href');
this.function2(url); // this is now overridden by jquery
});
}
function2(url) { if (this.alertUrl) alert(url); }
}
I am looking for a solution that would work like myModule.function2(url);, where myModule is only available to functions inside the module.
You can use an arrow function instead, so that the this reference is inherited from the outer scope, rather than being altered by the each callback:
html.find('a').each((_, elm) => {
var url = $(elm).attr('href');
this.function2(url);
});
Another (less elegant) option is to save a reference to the instance before calling the each:
function1(html) {
var self = this;
html.find('a').each(function () {
var url = $(this).attr('href');
self.function2(url);
});
}
The problem doesn't really have anything to do with modules, just the calling context of functions.
you can use async function with export like this...
const function_name = async () => {
};
export default function_name ;

calling a function on a function is it possible?

in the following code
const express = require('express');
const app = express()
app.use(express.static('public'));
express is a function so how it call "express.static('public')" method on it? is it possible in JavaScript to call a function which is inside a function
A functions is not only a first class function, but also a first class object and can contain properties.
function foo() {}
foo.bar = function () { console.log('i am bar'); };
foo.bar();
You can attach a function as member data to another function (which is what is done in your example).
const express = () => {};
express.static = argument => console.log('argument');
express.static('public'); # console >>> 'public'
However, you cannot readily access a variable that is defined in a function body.
const express = () => {
const static = argument => console.log('argument');
};
express.static('public'); # console >>> Error: undefined in not a function
There is a signifiant difference between member data attached to a function (the first example) and the closure that wraps the body of the function (the second example).
So, to answer your question "is it possible in JavaScript to call a function which is inside a function?" No, this is not readily possible with the important note that this is not what is being done in your example.
Actually, it is possible to call a function inside another function in javaScript.
So it depends on the condition, Callback is widely used in js
(A callback is a function that is to be executed after another
function has finished executing)
function doHomework(subject, callback) {
alert(`Starting my ${subject} homework.`);
callback();
}
function alertFinished(){
alert('Finished my homework');
}
doHomework('math', alertFinished);
And the second example can be Closures
(A closure is a feature in JavaScript where an inner function has
access to the outer (enclosing) function's variables)
function outer() {
var b = 10;
function inner() {
var a = 20;
console.log(a+b);
}
return inner;
}

Can I drop IIFE when I have const inside function in JavaScript

Let's say I have a function myFunction which in it's body uses results of other function otherFunction and those results are constant per every invocation.
function myFunction() {
doSomething(otherFunction());
}
In the past I used IIFE-s to invoke otherFunction only once and so optimize the code:
var myFunction = (function() {
let otherFunctionResult = otherFunction();
return function() {
doSomething(otherFunctionResult);
};
}());
I wonder if ES6 const keyword would achieve the same result without using IIFE:
function myFunction() {
const OTHER_FUNCTION_RESULT = otherFunction();
doSomething(OTHER_FUNCTION_RESULT);
}
Can I expect const to be optimized so that otherFunction is invoked only once? That would greatly simplify the code.
The fact that OTHER_FUNCTION_RESULT is declared as const doesn't mean it's only ever called once:
function callOften(){
const test = init(); // This is a `const`, but does it get called more often?
}
function init(){
console.log('Init Called');
return 1;
}
callOften();
callOften();
callOften();
Basically, your IIFE is one way to do what you want.
Yes, you don't need IIFEs any more in ES6. However, you seem to confuse const with what static does in other languages. You still need to initialise it outside of the function if you want to invoke otherFunction only once. It would look like this:
var myFunction;
{ // block scope!
let otherFunctionResult = otherFunction(); // `const` works the same here
myFunction = function() {
doSomething(otherFunctionResult);
};
}
Admittedly, an IIFE is still nicer to read if your module has a result (here: the function) that is supposed to be stored in a non-local variable.

Categories