This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 4 years ago.
Consider a simple pattern where we call setTimeout within a loop to print the loop counter:
function g(i){
return function()
{
console.log(i);
}
}
for(i=0;i<4;i++)
{
setTimeout(g(i),3000);
}
This returns the expected result:
0
1
2
3
According to my understanding, this function should do the same thing
function f(i){
this.n = i;
return function()
{
console.log(this.n);
}
}
for(i=0;i<4;i++)
{
setTimeout(f(i),3000);
}
Instead, I get varying results, in NodeJS:
undefined
undefined
undefined
undefined
And in Google Chrome:
3
3
3
3
Neither of these results make sense to me, so I was hoping someone else can explain this to me.
You can use an arrow function to keep your this:
function g(i){
return () =>
{
console.log(i);
}
}
for(i=0;i<4;i++)
{
setTimeout(g(i),3000);
}
Related
This question already has answers here:
Javascript function fails to return object when there is a line-break between the return statement and the object?
(2 answers)
Closed 5 years ago.
function aaa() {
return
{
test: 1
}
}
console.log(aaa());
Why this code result is undefined?
I assume is will be object.
Because when you change the line it terminate the statement so you have to put curly bracket after return to make it work.
Just use this:
function aaa() {
return {
test: 1
}
}
console.log(aaa());
This question already has answers here:
"add" function that works with different combinations of chaining/arguments
(4 answers)
Javascript:What is meaning of sum(2)(3) //returns 5;
(2 answers)
Closed 5 years ago.
Can Anybody help me to write this function
Write a function where the output for both “sum(2,3)” and “sum(2)(3)” will be 5
I think we need to write function using closer!
Syntax as follows: sum(2)(3) is related with currying. It means that you need to return another function inside the main function to get the desired result.
Here's a nice video about currying on Youtube, from which I've learned a lot.
function sum(a){
if (arguments.length == 1) {
return function(b){
return a + b;
}
} else {
return Object.keys(arguments).reduce((a,b) => arguments[a] + arguments[b]);
}
}
console.log(sum(2,3));
console.log(sum(2)(3));
As Karl-André Gagnon proposed, it can be also done with bind function.
function sum(a){
if (arguments.length == 1) {
return sum.bind(this, a)
} else {
return Object.keys(arguments).reduce((a,b) => arguments[a] + arguments[b]);
}
}
console.log(sum(2,3));
console.log(sum(2)(3));
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I'm using node.js with Q as promise implementation.
For some reason I have to build a few promise with a loop. In the "real" code, of course, I do not use constant in "for" loop.
I have an issue when I give i as parameter to my function buildPromiseForIdx. I expect to pass the value of i and expect the following result in the console.
-3
*3
but the code displays:
-3
*2
Here is the code:
function loop(promise, fn) {
return promise.then(fn).then(function (result) {
return !result ? loop(Q(result), fn) : result;
});
}
function buildPromiseForIdx(i) {
return getIdx(i*10).then(parseIdx);
}
// building promises for all idx page
var promises= [];
for (var i = 3 ; i >= 3 ; i--) {
log.debug('-'+i);
promises.push(loop(Q(false), function () { log.debug('*'+i);return buildPromiseForIdx(i)}));
}
The answer of the following question is also working in this case.
How do I pass the value (not the reference) of a JS variable to a function?
My loop is now:
var promises= [];
for (var i = 3 ; i >= 3 ; i--) {
log.debug('-'+i);
(function (i) {
promises.push(loop(Q(false), function () { log.debug('*'+i);return buildPromiseForIdx(i)}));
})(i);
}
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I've been reading up on Javascript closures and scope chains, but I haven't seen anything about maniuplating variables from within the scope chain. Here's a similar type of scenario I'm running into:
function first() {
var a = [];
a.push({firstFunction: 'yes'});
doSomethingFunction(valueToPassIn, function() {
a.push({secondFunction: 'yes'});
doAnotherThingFunction(newValueToPassIn, function() {
a.push({thirdFunction: 'yes'});
})
})
console.log(a) //returns {firstFunction: 'yes'}
}
how can I get it to return {firstFunction: 'yes', secondFunction: 'yes', thirdFunction: 'yes'}
The code may have syntax errors, but it's the idea I'm trying to understand. I just wrote this code up on the fly so you guys could see a similar scenario as to what I'm trying to fix.
Thanks
I know this was answered in the comments but here is an example of using a callback.
function first(callback) {
var a = [];
a.push({firstFunction: 'yes'});
doSomethingFunction(valueToPassIn, function() {
a.push({secondFunction: 'yes'});
doAnotherThingFunction(newValueToPassIn, function() {
a.push({thirdFunction: 'yes'});
callback(a);
});
});
}
first(function(a){ console.log(a); });
The only problem with this method is that it gets unruly when you have more than 3 or 4 nested callback functions. Promises are the way to handle it.
jsfiddle: http://jsfiddle.net/axqmvdxg/
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript closure?
This has probably been asked before, but...
If I want a list of functions
var funs = [
function(){ console.log(1); },
function(){ console.log(2); },
function(){ console.log(3); },
function(){ console.log(4); },
function(){ console.log(5); } ]
it would seem that one could make it by something like:
var funs = [];
for(var i=1; i <= 5; i++){
funs.push(function(){ console.log(i) };
}
Which doesn't work, as the variable i is a single variable bound to all the functions, so that
funs[0](); funs[1](); funs[2](); funs[3](); funs[4]();
outputs
6
6
6
6
6
not
1
2
3
4
5
This isn't the output I want. I guess I need to force javascript to bind a copy of the value of i at the time the function is created, instead of closing with the reference for i. How would I do this?
The easiest way is passing the function through the argument of a self-executing function:
for(...) {
(function(i) {
// here you have a new i in every loop
})(i);
}