So let's say I have the following code:
function c (f,i) {
let x = i;
if (f(x,i)){
x--;
}
if (f(x,2)) {
console.log(1);
}
else {
console.log(2);
}
}
what exactly happens in the if statements, I don't understand the syntax behind it.
f is no function, it's a variable, so what happens here? does it equal to f * ( x * i)? whats the operands behind this syntax.
Thanks in advance
A variable can also hold a function. It's possible to call c like this:
c(function(x, i) {/* do some check with x and i */}, 10);
In the if statements, the function you pass is called to do a check. A function like this is called a callback function. You have to pass it to the c function as in the example above. So if you call c, you can also determine how the check is done that c does.
Related
I heard that every function remembers(?) the lexical environment where the function had created.
In this code, The function function () { console.log(i);},
I want to know where this function had been created. If some function is a parameter of other function, where is the created(?)/generated point?
function countSeconds(howMany) {
for (var i =1; i <= howMany; i++) {
setTimeout(function () {
console.log(i);
}, i * 1000 );
}
};
In this code, The function function () { console.log(i);}, I want to know where this function had been created.
This function is defined as a function expression. Such an expression is evaluated at runtime, much like an expression { y: x*x } would be evaluated at runtime. But in this case the evaluation result is a function object. And that function is then passed as argument to setTimeout. This means there are just as many functions created as there are iterations of your for loop.
Now, even though the function expression is evaluated at the moment setTimeout is executed, this does not mean that the body of the function is executed at that same time. It is not. It will only be executed when the timeout expires. At that time the function body executes, and at that time only it will evaluate expressions used in that code, such as variable i. In your example, the variable i will already have reached the value howMany+1, because that for loop already ran to completion before the timer expired, and the callback got called.
If that is something you want to avoid, then use a separate variable i for each iteration of the for loop. With let instead of var you create such distinct variables, which only live inside the for loop's block. And so then each of the function expressions will reference its "own" i:
function countSeconds(howMany) {
for (let i =1; i <= howMany; i++) {
setTimeout(function () {
console.log(i);
}, i * 1000 );
}
};
countSeconds(10);
If some function is a parameter of other function, where is the created(?)/generated point?
Like all arguments to a function call, they're evaluated right before the function is called. You can rewrite this with two temporary variables into the equivalent
function countSeconds(howMany) {
for (var i=1; i<=howMany; i++) {
const __arg1 = function() {
console.log(i);
};
const __arg2 = i * 1000;
setTimeout(__arg1, __arg2);
}
}
The function is created when the function expression is evaluated.
(Also notice that this code has the famous closure in a loop problem.)
I dont understand what you mean?
You mean where the function console.log() ist defined?
class console {
log(text) {
[I dont know]
}
}
Then you can make "console.log()" to call the function "Log" from Claas console? Did you mean that?
I am a beginner at Javascript and am running into a little problem. It is a homework problem, but it is graded based on completion only, so I am only trying to figure out the right answer for myself.
I am supposed to define a function, repeatUntil, that takes in two other functions, say f(returns a number) and g (returns a boolean value). The functionality of repeatUntil is to repeat function f at least once until g returns true.
Here is what I have so far:
function repeatUntil(f, cond) {
var f1;
do{
f1 = f;
return f1;
}
while(cond(f1()));
}
And here is the tester/how we call it:
var print = console.log;
var r = repeatUntil(function(x) { return x + x }, function(x) { return x >= 20 })
print(r(2))
print("Expected: 32")
The function runs, but my problem right now is storing the updated value of x from the repeatUntil function. Right now the function only runs once, and the condition is not updated because I cannot pass in the updated value of x into the function g. I tried putting the result of f() into a variable, but it will only return a function and not a number.
Any help/advice would be greatly appreciated. Thank you!
Combining the existing comments into an answer.
Since you need to call r(), your function needs to return another function.
The do loop will run exactly once because you return in the body of the loop
Code
function repeatUntil(f, cond) {
return function() {
while(cond(f()));
}
}
Sorry, first attempt at explaining this question was poor. Trying to learn Javascript and a question from a code problem (codewars) has me stumped. It states, write a function that takes another function as a parameter and caches results so that if the same parameters are sent then the return is pulled from the cache and the actual function is not invoked again. For example:
var x = function(a, b) { a * b };
var cachedFunction = cache(x);
cachedFunction(4, 5); // function x should be executed
cachedFunction(4, 5); // function x should not be invoked again, instead the cached result should be returned
cachedFunction(4, 6); // should be executed, because the method wasn't invoked before with these arguments
I am not sure how to access the arguments sent via cachedFunction. The goal is to write cache so that it can handle a function x with any number of arguments.
What you're describing is not possible.
The expression x(5, 4) is evaluated before the cache() function is even called. It's not receiving a function. It's receiving the value 20.
In your example, cache only has access to the return value of x. It can't know anything about how this return value was computed (i. e. by calling x with parameters 5, 4).
You would need to separately pass the function and its parameters to the cache function, e. g. as follows:
function cache(func, ...params) {
// Todo: do something with params
return func(...params);
}
function x(a, b){
return a * b;
}
console.log(cache(x, 5, 4));
you can return a table like this:
function x(a,b){
return [a, b, a*b];
}
after that you can get the params like this:
var result=x(values1,value2);
console.log(result[0]);// a == value1
console.log(result[1]);// b == value2
console.log(result[2]);// a*b == value1*value2
I have wrote a code in javascript like
function onClic(){
var i = 0;
if ( i==2 ){
var m = function(){
return 1;
}
}
else {
var m = function(){
return 2;
}
}
alert(m());
}
the alert shows 2;
can you please explain me the behavior in this statement i.e. Why am I able to access m outside the If statement when I declared it inside If statement scope.
Also why is this working as ECMAScipt 5 specifies that we donot put the function declaration inside IF-ElSE block.
Why am I able to access m outside the If statement when I declared it inside If statement scope.
Because JavaScript (ES5 at least, has only function scope, not block scope. The if statement does not create scope. Your code is equivalent to:
function onClic(){
var i = 0;
var m; // m is "hoisted"
if ( i==2 ){
m = function(){
return 1;
}
}
else {
m = function(){
return 2;
}
}
alert(m());
}
Also why is this working as ECMAScipt 5 specifies that we donot put the function declaration inside IF-ElSE block.
Right, but what you have are function expression, not declarations. A function declaration is something like
function foo() { }
Function expressions can be put everywhere where an expression is valid to use.
While you are right that, according to the spec, function declarations cannot be used inside blocks, browser still allow it and actually produce different results. Run this in Firefox and Chrome:
function foo() {
alert(1);
}
if (false) {
function foo() {
alert(2);
}
}
foo();
However, this will change in ES6 where this behavior will be properly defined.
Your variable i is set to 0 at the start of your function. You never change it. You IF statement is testing if i is equal to 2; it isn't. So it jumps to the ELSE statement, and returns 2.
If you want it to do something, you never to change the value of i in some way that makes sense to the problem you are trying to solve.
function onClic(){
var i = 0;// set i=0
if ( i==2 ){ // so this condition always give false and control go to else statement
var m = function(){
return 1;
}
}
else {
var m = function(){
return 2;
}
}
alert(m());
Just saw what you were actually asking.
The variable is still inside the onClic() function so it is still in the local scope even though it is within an if statement.
First you are checking for value of variable i in your function
If condition check the value of i , if it is 2 it makes a function assignment to variable m the function returns 1
if value of i is not 2 it makes a function assignment to variable m the function returns 2
In the end you call m that return either 2 or 1.
my variable is inside the scope of If statement then how am I able to
get its value outside the scope in the last round
The answer is in js you dont have block level scope , you have either global scope or local scope. Here I is local varaible so it can be accessed any where in this function
I have a function as below:
function callme(x,y) {
return function() {
console.log("value of x = " + x);
console.log("value of y = " + y);
}
}
I would like to add the above function to an array and then execute them
var steps = [];
steps.push(callme(1,2));
steps.push(callme(2,3));
steps[0]; // should execute first function
steps[1]; // should execute second function
For some reason the parameters I am passing to the function are not getting stored.
Anyone anyclues as to what I might be doing wrong ?
You're not actually calling the methods. Calling methods involves using the bracket syntax as shown below:
steps[0](); // should execute first function
steps[1](); // should execute second function
Edit
Jared has kindly worked up a JSFiddle.
Second Edit
In your comments you've asked for added callback functionality. Even though this should probably be a separate question, I'll throw a bone for now:
function callme(x, y, callback) {
return function() {
console.log("value of x = " + x);
console.log("value of y = " + y);
callback();
}
}
I'm assuming you'll want to call the functions programmatically in order (from your array), so you'll probably need something like this:
var steps = [];
steps.push(callme(1, 2, next));
steps.push(callme(2, 3, next));
var i = -1;
function next(){
i++
if(i < steps.length){
steps[i]();
}
}
next();
It should be noted though that this sort of sequential calling of methods can be a slippery slope. Mainly because your callback method is being called before the last callback has finished executing, leading to possible stack overflow errors.
You're better off looking into design patterns: middleware and promises is a good place to start.
you should call like this
steps[0]();
steps[1]();
In order to execute each function, you need to invoke it.
So this line steps[0] should actually look like this steps[0]()
EDITED. Bad answer on my part as I somehow overlooked the fact that callme() indeed returns a function.