JavaScript Nested Function

JavaScript Nested function

Functions are another type of variable in JavaScript (with some nuances of course). Creating a function within another function changes the scope of the function in the same way it would change the scope of a variable. This is especially important for use with closures to reduce total global namespace pollution.

The functions defined within another function won't be accessible outside the function unless they have been attached to an object that is accessible outside the function:

function foo(doBar)
{
function bar()
{
console.log( 'bar' );
}

function baz()
{
console.log( 'baz' );
}

window.baz = baz;
if ( doBar ) bar();
}

In this example, the baz function will be available for use after the foo function has been run, as it's overridden window.baz. The bar function will not be available to any context other than scopes contained within the foo function.

as a different example:

function Fizz(qux)
{
this.buzz = function(){
console.log( qux );
};
}

The Fizz function is designed as a constructor so that, when run, it assigns a buzz function to the newly created object. That is, you'd use it like this:

const obj = new Fizz();
obj.buzz();

or more concisely (if you don't need to keep the object after calling buzz):

new Fizz().buzz();

Nested function (Javascript)

// Cache the elements and add a click listener to the buttonconst out = document.getElementById('out');const button = document.querySelector('button');button.addEventListener('click', cal, false);
function abc() { var radius = document.f1.rd.value;
// Instead of using `document.write` // append the value to the output div out.innerHTML += radius + '<br />';}
function def() { var fala = document.f1.fala.value; out.innerHTML += fala + '<br />'}
function cal(e) {
// Prevent the form from submitting to the server e.preventDefault(); def(); abc();}
<form name="f1">  <label>RD</label><input name="rd" />  <label>FALA</label><input name="fala" />  <button>Cal!</button></form><div id="out"></div>

Javascript call nested function

    function initValidation()    {        // irrelevant code here        function validate(_block){            console.log( "test", _block );        }            initValidation.validate = validate;    }
initValidation(); initValidation.validate( "hello" ); //test hello

How to call nested function in javascript?

In general, you can't. The point of defining a function inside another function is to scope it to that function.

The only way for b to be accessible outside of a is if (when you call a) you do something inside a to make it available outside of a.

This is usually done to create a closure, so that b could access variables from a while not making those variables public. The normal way to do this is to return b.

function a() {
var c = 0;
function b() {
alert(c++);
}
return b;
}
var d = a();
d();
d();
d();
var e = a();
e();
e();
e();

What are the uses or advantages of nested functions?

This is not so much about nested functions but about schönfinkeling / currying. Schönfinkeling / currying is named after Moses Schönfinkel who developed this technique (after Gottlob Frege had previously introduced it) and Haskell Curry, who perfected and described it.

In simple terms, currying is a technique that allows to turn any function of n arguments into a function of n-1 arguments which returns a function that takes the nth argument. And by applying this repeatedly, you can show that you never need functions of more than one argument, to model functions with arbitrary many arguments.

Here is an example. I can turn a function that adds two numbers:

function add(a, b) { return a + b; }

add(2, 3)
//=> 5

Into an "adder factory" that returns adder functions, which when called will then produce the sum of the two numbers:

function adderFactory(a) {
return function adder(b) { return a + b; };
}

const twoAdder = adderFactory(2);
twoAdder(3)
//=> 5

or

adderFactory(2)(3)
//=> 5

Now, you might think: "but ECMAScript supports functions with more than one argument, so why would I simulate them using currying, if I can have them natively?" And you would be right! It makes no sense to use currying for this reason.

But, there is another interesting thing that you might want to do with functions: partial application. "Function application" is just functional programming speak for "calling a function", so "partial application" means "calling a function with only a subset of its arguments". Partial application calls a function with only some of its arguments, and produces a function that is specialized for only those arguments. In a language that supports partial application, I could do something like this:

const fourAdder = add(4, ?);

But, ECMAScript doesn't have partial application.

However, when I curry my functions, then I can do "sort-of partial application", where I can at least only supply the first few arguments, and leave out the last few arguments. This means that you have to think about which arguments are more likely to be fixed and which arguments are more likely to be variable, and you should order them by "variability".

So, in the case of the function that you posted, it is possible to create a base converter that can only convert one specific number from one specific base into any number of bases. I must admit, that is actually not terribly useful. It would be much more useful if the function were defined like this:

const convertFromBaseToBase = baseFrom =>
baseTo =>
num => parseInt(num, baseFrom).toString(baseTo);

convertFromBaseToBase(2)(8)('1001')
//=> '11'

Now, you can, for example, create a converter from octal to hexadecimal like this:

const octalToHexadecimalConverter = convertFromBaseToBase(8)(16);

octalToHexadecimalConverter('17')
//=> "F"

Note! With the restriction that you can only "partially apply from the right", you could actually also do this with optional parameters with default arguments, kind of like this:

const baseToToken = Symbol('baseTo'),
numToken = Symbol('num');

function convertFromBaseToBase(baseFrom, baseTo=baseToToken, num=numToken) {
if (num === numToken) {
if (baseTo === baseToToken) {
return (baseTo, num=numToken) =>
num === numToken ?
num => parseInt(num, baseFrom).toString(baseTo) :
parseInt(num, baseFrom).toString(baseTo);
} else {
return num => parseInt(num, baseFrom).toString(baseTo);
}
} else {
return parseInt(num, baseFrom).toString(baseTo);
}
}

convertFromBaseToBase(8, 16, '17')
//=> 'F'

convertFromBaseToBase(8, 16)('17')
//=> 'F'

convertFromBaseToBase(8)(16)('17')
//=> 'F'

convertFromBaseToBase(8)(16, '17')
//=> 'F'

But, as you can see, this starts to get real ugly, real fast.

The snippet in the question also is useful for another reason: it provides a fluent interface which gives names to the particular parameters, so that you can not confuse the two number parameters baseFrom and baseTo. This can, however, also be solved in a couple of other ways. One is by naming the function such that it is clear whether the baseFrom or the baseTo comes first, i.e. instead of convertBase(num, baseFrom, baseTo) call it convertNumberFromBaseToBase(num, baseFrom, baseTo). Another possibility would be to use an object parameter, like this:

function convertBase({ num, baseFrom, baseTo }) {
return parseInt(num, baseFrom).toString(baseTo);
}

convertBase({ num: '17', baseFrom: 8, baseTo: 16 })
//=> 'F'

But, even when using a more descriptive function name or a fluent interface, then it would still make sense to change the order of parameters, to make currying and partial application more useful.

Note also that I haven't said anything at all about nested functions that are not used for currying, as in this case, for example [Code adapted from Ruby Recursive Indexing/Searching Method (Using Middle Comparison) Returning Incorrect Index Value]:

function bsearch(arr, target) {
function bsearchRec(arr, target, offset=0) {
const middleIndex = Math.floor(arr.length / 2);

if (arr[middleIndex] === target) { return offset + middleIndex; }
if (arr.length === 1) { return undefined; }

if (target > arr[middleIndex]) {
return bsearchRec(arr.slice(middleIndex+1), target, offset + middleIndex + 1);
} else if (target < arr[middleIndex]) {
return bsearchRec(arr.slice(0, middleIndex), target, offset);
}
}

return bsearchRec(arr, target);
}

bsearch([1, 3, 4, 5, 9], 5)
//=> 3

Here, the nested function bsearchRec is nested inside bsearch because it is a private internal implementation detail of bsearch, and nobody except the author of bsearch should know about it.

And lastly functions are the vehicle used in ECMAScript for encapsulation. In particular, functions are how ECMAScript implements objects. Objects have behavior identified by names, and encapsulation. In most OO languages, those three things, the behavior, the encapsulation, and the mapping of names to behavior (aka "method calls") are provided by one entity, the object. In ECMAScript, encapsulation is provided by functions (closures), behavior is provided by functions (nested inside closures to share private state), and the mapping from names to behavior is provided by dictionaries, which are confusingly called objects, even though they only implement one third of what it means to be an object.

So, without nested functions, there would be no encapsulation in ECMAScript, and most importantly, no objects! Even modules and classes are mainly syntactic sugar on top of nested functions.

Add a nested function to a function body dynamically in JavaScript

Well, if you ask "is it possible", then the answer is sadly yes:

  function cow(fn) {
let see = "oh no";
eval(fn.toString())();
}

cow(function moo() {
console.log(see);
});

But except for this hack, it isn't really possible, because JavaScript has lexical scoping, which means that only the position in the source code determines which variables a function can access. You cannot change the position in the source code (except you dynamically evaluate strings as code, which you should not).

If it is just about calling some function dynamically, without accessing variables from the outer function, then you can just pass a function as a parameter (which is actually quite usual in JavaScript):

  function cow(moo) {
moo();
}

cow(function mooo() {
console.log("mooo");
});

For sure you could then also pass arguments into the moo() call and receive them in the mooo function (or any other function).

Javascript abort execution of a nested function

From the above comments ...

"It sounds like the OP is in need of an abstraction which wraps functions that have to be time and/or condition based and repeatedly invoked into cyclically running (or better clocked) functions which e.g. can get actively terminated. One answer to How does one terminate a counter process which runs in timed intervals? provides both the implementation and a lot of running example code."

''Let's suppose invoking child triggers an interval of a child related process. Now the OP states ... "I would like to abort [the] execution of [the] child [interval] if main function is called". Let's suppose this can be achieved from within the main function. Wouldn't invoking child (as implemented with the current main function) not immediately trigger a new child related interval again?''

Example code ...

function childProcess(text) {
console.log(text);
}
const clockedChildProcess = childProcess.clocked(1000);

function main(text) {
clockedChildProcess.terminate();

clockedChildProcess(text);
}

function init() {
document
.forms[0]
.addEventListener('reset', evt => {

clockedChildProcess.terminate();
console.clear();
});
document
.forms[0]
.addEventListener('submit', evt => {
evt.preventDefault();

main(evt
.currentTarget
.elements[1]
.value
);
});
}
init();
body { margin: 0; }
fieldset { margin: 0; padding: 0 3px 4px 3px; }
fieldset [type="text"] { width: 50%; }
.as-console-wrapper { min-height: 75%; top: auto; }
<script>

(function (global, Reflect, Math, Number, Array, Function) {

'use strict';

const DEFAULT_INTERVAL = 200;

const { isFinite, parseInt } = Number;
const { setInterval, clearInterval } = global;

function isFunction(value) {
return (
typeof value === 'function' &&
typeof value.call === 'function' &&
typeof value.apply === 'function'
);
}

function getSanitizedTarget(value) {
return value ?? null;
}

function getSanitizedInteger(value) {
value = parseInt(value, 10);
return isFinite(value) ? value : 0;
}
function getSanitizedPositiveInteger(value) {
return Math.max(getSanitizedInteger(value), 0);
}

function createClockedFunction(interval, target, controller) {
const proceed = this;

let thisArg;
let argsArr;

let clockCount = null;
let clockStart = null;

let timerId = null;

target = getSanitizedTarget(target);
interval = getSanitizedPositiveInteger(interval) || DEFAULT_INTERVAL;

function triggerController() {
controller({
clock: {
interval,
startTime: clockStart,
timestamp: Date.now(),
count: ++clockCount,
},
target: thisArg,
args: [...argsArr],
proceed,
terminate,
});
}
function triggerProceed() {
proceed.apply(thisArg, argsArr);
}

function terminate() {
clearInterval(timerId);
timerId = null;

clockStart = null;
clockCount = null;
}

function isActive() {
return (timerId !== null);
}

function clocked(...argumentsArray) {
thisArg = getSanitizedTarget(this) ?? target;
argsArr = argumentsArray;

if (isActive()) {
terminate();
}
clockCount = 0;
clockStart = Date.now();

const trigger = isFunction(controller)
? triggerController
: triggerProceed;

timerId = setInterval(trigger, interval);
}
clocked.terminate = terminate;
clocked.isActive = isActive;

return (isFunction(proceed) && clocked) || proceed;
}
createClockedFunction.toString = () => 'clocked() { [native code] }';

Reflect.defineProperty(Function.prototype, 'clocked', {
configurable: true,
writable: true,
value: createClockedFunction,
});

}((window || global || this), Reflect, Math, Number, Array, Function));

</script>

<form>
<fieldset>
<legend>log update</legend>
<input type="text" value="Hallo World!" />
<button type="submit">log</button>
<button type="reset">terminate / reset</button>
</fieldset>
</form>


Related Topics



Leave a reply



Submit