function say(something) {
console.log(something);
}
function exec(func, arg) {
return func(arg);
}
exec(say, "Hi, there.");
Why does this code work? I feel like it shouldn't since what is in the second function should return
say(something) (arg) {
console.log(something) ;
}
It works as it does because when you write return func(arg);, the func(arg) bit executes the function. What is returned is then the result of executing func(arg).
However, you're right that say() doesn't actually return a value, it just logs to the console within that function. The output you're seeing is the result of that log command. If you logged the returned value instead you'd see undefined as the result.
But if you'd passed a different function to exec which did return a value, then you'd need the return in exec() for it to work properly.
P.S. I'm not sure if this is part of what you're asking, but the difference between that and when you wrote exec(say, "hi there"); is that in that code, say is a reference to the "say" function. At that moment it's treated like any other variable, just the same as if you passed in a number or a string, for example.
The difference is the (), which causes the function to be executed, rather than passed as a reference.
In the question you seem to imply that you'd expect the source code of the say() function to be displayed, but this is not what it does, and also is not possible anyway.
Function say returns undefined (default value if no return keyword is used), and therefore function exec also returns undefined.
Proof:
function say(something) {
console.log(something);
}
function exec(func, arg) {
var result = func(arg);
console.log(result);
return result;
}
var result2 = exec(say, "Hi, there.");
console.log(result2);
Maybe you are looking for a closure, where exec returns a function for getting arg for the first handed over function func.
function say(something) {
console.log(something);
}
function exec(func) {
return function (arg) {
return func(arg);
};
}
exec(say)("Hi, there.");
Related
I'm trying to understand exactly how this Once function by David Walsh works:
`
function once(fn, context) {
var result;
return function() {
if(fn) {
result = fn.apply(context || this, arguments);
fn = null;
}
return result;
};
}
// Usage
var canOnlyFireOnce = once(function() {
console.log('Fired!');
});
canOnlyFireOnce(); // "Fired!"
canOnlyFireOnce(); // nada
`
I understand it takes a function as a argument, and returns a function that calls the passed function only once.
But I'm trying to understand what each part is doing. Can anyone help explain? especially this part:
result = fn.apply(context || this, arguments);
Why the OR sign? what is "this" and how is it getting the arguments from fn? What purpose does 'context' serve?
I wrote a similar once() function for school that returns the result of the passed function, and stores the result to return it again if the function attempts to get called again. It took a lot of trial and error, and I'm just trying to get a firm grasp on all the component parts of how this works.
`
function add(x, y) {
return x + y;
}
function once(fn) {
let timesRan = 0;
let result;
function doOnce() {
if (timesRan === 0) {
timesRan = 1;
result = fn.apply(this, arguments); //I don't understand how this gets the arguments from AddOnce
console.log(`did it once: ${result}`)
return result;
} else {
return result;
}
}
return doOnce;
}
var addOnce = once(add);
console.log(addOnce(1, 2)); // test first call, expected value: 3
console.log(addOnce(2, 5)); // test second call, expected value: 3
console.log(addOnce(8, 22)); // test third call, expected value: 3
`
The concept behind this in JavaScript is confusing, because when I write a function such as:
function getPersonName() {
return this.name
}
I expect that this be defined as a some object with a name attribute. Depending on the scope, I may have this be defined and no problems! But in order for a function such as the above to properly reference this, we need to tell it what it should reference when we use that keyword.
For example, it allows us to do the following:
var canOnlyFireOnce = once(function() {
console.log(this.name)
}, {name: "John"});
canOnlyFireOnce() // prints John
canOnlyFireOnce() // nada
It may be helpful to understand the bind function's use cases in JavaScript to understand why having this (no pun intended) is useful.
The meaning of the this context in function.apply is already explained in rb612's answer.
For the question about arguments, you need to know that
the arguments object is a local variable available within all non-arrow functions. You can refer to a function's arguments inside that function by using its arguments object.
function person1(name) {
var n = name;
return (function (n) {
alert(n);
})(n);
}
person1('susan')();
person1('peter')();
The second statement cannot be run, anyone can give me a correct explanation.
person1('susan') does not return a function, it returns undefined, so you can't call it afterwards - the extra () results in the script throwing.
If you want calling person1 to return a function that, when called, alerts the name, remove the n parameter, and return a function that alerts name - but don't call the function, just return it, so the returned function can be called outside:
function person1(name) {
return () => {
console.log(name);
};
}
person1('susan')();
person1('peter')();
The code of your function is basically ok but the call person1 is not. You should omit the brackets after the call. Because your not returning a function back from person1. Actually you don't have a return value at all.
function person1(name) {
var n = name;
return (function (n) {
alert(n);
})(n);
}
person1('susan');
person1('peter');
This would work but can be simplified.
I just wanted to understand whats happening with this code, and I searched deep into the subject of nested functions and higher order, plus the return statement. But still I wanted to put an end to this doubt(unsure about two return statements in a row) which led me here and help is needed for my understanding, as well to all that apply.
function higher_order(){
return function addNum()
{
return 1+1;
return function subNum()
{
return 1-1;
};
};
};
alert(higher_order()()());
The problem is that the function stops running after the first return statement; your higher_order returns the function addNum, which returns the number 2; this is not callable, and the exception occurs at the 3rd parentheses ()
higher_order() returns function addNum()
addNum() returns number 2
2 (higher_order()()) is not callable as a function, thus you get an exception.
You might try alert(higher_order()()) to see what is the value used for the third call.
// Try this way:
function higher_order(){
return function addNum(){
return function subNum(){
return 1-1;
};
};
};
higher_order() // returns the function addNum
higher_order()() // returns the function subNum
higher_order()()() // returns the value returned from subNum (0)
Please consider this javascript:
var a = function(arg1) {
alert(arg1);
}
a("hello");
a(function() { return "world"; });
How do I get it to return "world" in the second call? Right now it returns the whole function as a string.
Just execute the function expression, it will return world and that will be passed to the a function
a((function() { return "world"; })());
DEMO
You need to call the function, not just refer to it:
alert(arg1());
If you need to cope with a being called with either a string or a function, you'll need to check the type of the argument with typeof and handle them differently.
With the second call arg1 is a function.
To get the result you have to execute the function:
alert(arg1());
I was wondering whether this is legal to do. Could I have something like:
function funct(a, foo(x)) {
...
}
where a is an array and x is an integer argument for another function called foo?
(The idea is to have one function that uses a for loop on the array, and calls that function in the params for every element in the array. The idea is so call this on different functions so elements of two arrays are multiplied and then the sums are added together. For example A[0] * B[0] + A[1] * B[1].)
I think this is what you meant.
funct("z", function (x) { return x; });
function funct(a, foo){
foo(a) // this will return a
}
This is not the way to declare a function with another function as one of it's parameters. This is:
function foodemo(value){
return 'hello '+ value;
}
function funct(a, foo) {
alert(foo(a));
}
//call funct
funct('world!', foodemo); //=> 'hello world!'
So, the second parameter of funct is a reference to another function (in this case foodemo). Once the function is called, it executes that other function (in this case using the first parameter as input for it).
The parameters in a function declaration are just labels. It is the function body that gives them meaning. In this example funct will fail if the second parameter wasn't provided. So checking for that could look like:
function funct(a, foo) {
if (a && foo && typeof a === 'string' && typeof foo === 'function'){
alert(foo(a));
} else {
return false;
}
}
Due to the nature of JS, you can use a direct function call as parameter within a function call (with the right function definition):
function funct2(foo){
alert(foo);
}
funct2(foodemo('world!')); //=> 'hello world!'
If you want to pass a function, just reference it by name without the parentheses:
function funct(a, foo) {
...
}
But sometimes you might want to pass a function with arguments included, but not have it called until the callback is invoked. To do this, when calling it, just wrap it in an anonymous function, like this:
funct(a, function(){foo(x)});
If you prefer, you could also use the apply function and have a third parameter that is an array of the arguments, like such:
function myFunc(myArray, callback, args)
{
//do stuff with myArray
//...
//execute callback when finished
callback.apply(this, args);
}
function eat(food1, food2)
{
alert("I like to eat " + food1 + " and " + food2 );
}
//will alert "I like to eat pickles and peanut butter"
myFunc([], eat, ["pickles", "peanut butter"]);
And what would you like it to achieve? It seems you mixed up a function declaration with a function call.
If you want to pass another calls result to a function just write funct(some_array, foo(x)). If you want to pass another function itself, then write funct(some_array, foo). You can even pass a so-called anonymous function funct(some_array, function(x) { ... }).
I would rather suggest to create variable like below:
var deleteAction = function () { removeABC(); };
and pass it as an argument like below:
removeETC(deleteAction);
in removeETC method execute this like below:
function removeETC(delAction){ delAction(); }
What you have mentioned is legal. Here, foo(X) will get called and its returned value will be served as a parameter to the funct() method
In fact, seems like a bit complicated, is not.
get method as a parameter:
function JS_method(_callBack) {
_callBack("called");
}
You can give as a parameter method:
JS_method(function (d) {
//Finally this will work.
alert(d)
});