Passing a function into another function - javascript

I have a function that is similar to this:
function foo(array1, fun) {
var n;
n = a.length;
var i;
for (i=0; i<=n; i++) {
fun(a[i]);
}
}
Now I want to create a function called mult(x) that I will pass into foo when I call it. My question is what do I put in the parameters of my mult function when I want to call:
foo(some_array, mult(x));

Just pass in a reference to it (its name only)...
foo(some_array, mult);
Alternatively, pass in an anonymous function...
foo(some_array, function() { ... });
The first argument of this function you pass in with will be set to a[i] like in the body on your function.

Rewritten to showcase how you call a function in JS
function mult(x){
//do stuff to x
}
function foo(array1, fun){
var n = array1.length;
var i;
for (i=0; i<=n; i++) {
mult(array1[i]);
}
}

Related

To modify this keyword in Javascript

How should I replace the this with the original calling object? I understand this is a simplified way to present it but I was trying to understand the object that the this was referencing to.
for(var i=0; i<list.length; i++){
list[i].addEventListener("click", liClick);
}
function liClick(){
this.classList.toggle("done");
}
My understanding is that this is referring to the list[i] which has been clicked, but when I tried with
function liClick(){
list[i].classList.toggle("done");
}
it was wrong, how should I modify it? Thanks.
You can do something like this:
for (var i = 0; i < list.length; i++) {
list[i].addEventListener("click", liClick);
}
function liClick(e) {
e.target.classList.toggle("done");
}
this keyword doesn't refer to list item.
You should pass list[i] to function
the function listClick receive event and you can directly access e.target or make callback function and pass item
for(var i=0; i<list.length; i++){
list[i].addEventListener("click", () => liClick(list[i]) );
}
const liClick = (listItem) => {
listItem.classList.toggle("done");
}

jQuery pass argument to $.get() callback function

I am using this piece of code to retrieve some JSONs from twitch:
for (var i = 0; i < streamList.length; i++) {
$.get(baseURL + streamList[i], getStreamInfo, "json");
}
where getStreamInfo is the callback function. I would like to know if it is possible to pass the value of "i" to the callback function somehow, along with the JSON.
Yes, you can pass the default parameter that receive the data of the ajax query and then add the i var.
for (var i = 0; i < streamList.length; i++) {
$.get(baseURL + streamList[i],
function(data) { getStreamInfo(data, i) },
"json");
}
Note that you need to receive it in getStreamInfo function
Hope it helps.
You can add any variables you want to the anonymous object. Be sure those variables are not used by the get function.
For exemple, I added the variable foo to the anonymous object and used it with this.foo in the callback function :
for (var i = 0; i < streamList.length; i++) {
$.get({
url: baseURL + streamList[i],
success: getStreamInfo,
dataType: "json",
foo:i
});
}
function getStreamInfo()
{
var i = this.foo;
}
You can use Closures.
for (var i = 0; i < streamList.length; i++) {
(function(index){
$.get(baseURL + streamList[i], function(data){
getStreamInfo(data, index);
}, "json");
})(i);
}
Note: Modify your function getStreamInfo to accept index.
Read How do JavaScript closures work?

Calling nested function using javascript

I have this code which calls a function test() on body onload
<body onLoad="test();">
The Test function has 2 more functions drawLayers() ,StopAll().
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
timers.push(setTimeout(drawCircle3,3100));
timers.push(setTimeout(drawCircle4,3500));
timers.push(setTimeout(drawCircle5,3900));
timers.push(setTimeout(drawtext2,4300));
timers.push(setTimeout(drawtext,4700));
timers.push(setTimeout(drawtext3,5100));
timers.push(setTimeout(drawtext4,5500));
timers.push(setTimeout(drawtext5,5900));
timers.push(setTimeout(drawtext6,6300));
timers.push(setTimeout(drawtext7,6700));
timers.push(setTimeout(drawtext8,7100));
timers.push(setTimeout(drawtext9,7500));
timers.push(setTimeout(drawtext10,7900));
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
}
What i want to do is Call the StopAL() function on click of a button, the html code looks like below
<a href="javascript:void(0);" onClick="StopAll();">
Its throwing error, "StopAll is not defined"
How do i call the StopALL() function?
The scope of those nested functions is restricted to the test function only. You cannot invoke them from the outside. If you need to do that you could externalize it from the test function.
This is a 'closure' problem. The function StopAll is within the scope of the test function, and therefore is undefined in the global scope in which you are trying to call it.
Closures are a tricky subject to grasp initially. There's a good explanation here:
How do JavaScript closures work?
(by the way StopAll should really be called stopAll because capitalised functions are generally reserved for use with the new keyword.)
test = function (){
this.drawLayers = function() {
this.timers = [];
this.timers.push(setTimeout(drawMoon,800));
}
this.StopAll = function() {
alert('fsdfsdf');
var t = timers.length
for (var i = 0; i < t; i++)
window.clearTimeout(this.timers[i]);
}
}
var testObj = new test();
testObj.StopAll()
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
}
var StopAll=function() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
return StopAll;
}
var obj= new test();
//to call StopAll function
obj();
(function test($) {
function drawLayers() {
}
//expose this to outside world ,public function
$.StopAll = function() {
alert('fsdfsdf');
}
})(window);
StopAll();
You'd better not use html attributes to bind event handler, you can do the same with the following code:
window.onload = function(){
document.getElementById("myLink").onclick = function(){
StopAll();
}
}
// Your functions
This way you'll ensure your dom is loaded and ready to call event handlers.
You can move the function StopAll() outside the test function and call it as specified. If suppose you need to access that function even in the test(), you can do like this
function test() {
.....
drawLayers();
StopAll() ;
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
Declaration of function can be given outside and called any where you want

How to pass parameter to an anonymous function defined in the setTimeout call?

Here is my code:
function addRcd2(timeOut){
for(var c=0; c less 5; c++){
var rcdi = "rcd_"+c+"";
setTimeout(function(){
$('.tbl1 tbody').append(rcdi);
},timeOut*c);
}
}
The output of this code is a table which rows have the same text rcd_5.
My goal is to have a table rows have different records rcd_1, …, rcd_5.
Any ideas?
Typical creating a function in a loop problem. All closures you pass to setTimeout have a reference to the same rcdi variable. Defining the variable inside the loop is the same as defining it outside:
var rcdi;
for(var c=0; c < 5; c++){
rcdi = "rcd_"+c+"";
// ...
}
which makes it a bit more apparent that you only deal with one variable here.
You have to introduce a new scope, which in JavaScript can only be achieved through functions:
function getCallback(val) {
return function(){
$('.tbl1 tbody').append(val);
};
}
function addRcd2(timeOut){
for(var c=0; c < 5; c++){
setTimeout(getCallback("rcd_"+c),timeOut*c);
}
}
As you can see in other answers, you can also use immediate functions. Use what you find more readable.
function addRcd2(timeOut){
for(var c=0; c less 5; c++){
var rcdi = "rcd_"+c+"";
setTimeout((function(x) {
return function(){
$('.tbl1 tbody').append(x);
};
})(rcdi),timeOut*c);
}
}

Arguments to JavaScript Anonymous Function

for (var i = 0; i < somearray.length; i++)
{
myclass.foo({'arg1':somearray[i][0]}, function()
{
console.log(somearray[i][0]);
});
}
How do I pass somearray or one of its indexes into the anonymous function ?
somearray is already in the global scope, but I still get somearray[i] is undefined
The i in the anonymous function captures the variable i, not its value. By the end of the loop, i is equal to somearray.length, so when you invoke the function it tries to access an non-existing element array.
You can fix this by making a function-constructing function that captures the variable's value:
function makeFunc(j) { return function() { console.log(somearray[j][0]); } }
for (var i = 0; i < somearray.length; i++)
{
myclass.foo({'arg1':somearray[i][0]}, makeFunc(i));
}
makeFunc's argument could have been named i, but I called it j to show that it's a different variable than the one used in the loop.
How about a closure:
for (var i = 0; i < somearray.length; i++) {
var val = somearray[i][0];
myclass.foo({'arg1': val}, function(v) {
return function() {console.log(v) };
}(val) );
}
for (var i = 0; i < somearray.length; i++)
{
myclass.foo({'arg1':somearray[i][0]}, function(somearray)
{
console.log(somearray[i][0]);
});
}
And then in method foo call anonymous function with param.
You can pass variables values to annoymous function by using callback,
something like
myclass.foo(function(variable){
return function(){
console.log(variable);
}
})(variableValue);
);
check this post: https://shahpritesh.wordpress.com/2013/09/06/javascript-function-in-loop-passing-dynamic-variable-value/
All the functions/methods can be used as callbacks only. When you call the callback function you pass variables to it.
var myclass = {
foo: function(params, callback){
// do some stuff
callback(variable1, variable1, variableN);
}
}

Categories

Resources