I'm brushing up on knowledge of Javascript and filling in some of the gaps.
for the memoize function, I get why it would console log the function as the memoizeSomeFunction const is just a function expression of someFunction being passed into memoize as an arg. what I can't seem to conceptualize is how the arg being passed into memoizeSomeFunction gets to the return part of the function. can someone elaborate?
const memoize = (fn) => {
console.log(fn);
return (arg) => {
console.log(arg)
}
}
const someFunction = (x = 0, y = 0) => {
return `x is {$x} y is ${y}`;
}
const memoizeSomeFunction = memoize(someFunction);
memoizeSomeFunction(1)
The memoize() function returns a function:
(...args) => {
console.log(...args)
}
That function collects its arguments into an array using the spread (...) syntax, and then un-collects them the same way in the console.log() call.
Thus when you call the function returned from memoize(), it simply logs the arguments passed.
To summarize:
Just one argument is passed to memoize(), your someFunction() function;
The memoize() function returns another function, and that function logs its arguments (and otherwise does nothing with someFunction());
The function source is logged when memoize() is called, and the argument list to the return value from that is logged whenever it is called. If you added another call to that returned function, you'd see those arguments logged separately.
// ES5 equivalent:
const memoize_es5 = function(fn) {
// fn is closured and can be used
// function returned, when it will be called we will have call arguments as well
return function () {
console.log(fn.apply(null, arguments));
}
}
const memoize = fn => (...args) => console.log(fn(...args));
const someFunction = (x = 0, y = 0) => {
return `x is ${x} y is ${y}`;
}
const memoizeSomeFunction = memoize(someFunction); // function received as result of memoize call
memoizeSomeFunction(1, 15); // pass arguments to that function function
// ...args in the arguments is a rest operator
// it just capture all rest arguments into an array:
((first, ...args) => console.log(first, args))(1, 2, 3)
// ...args in a function call is spread operator
// it spreads an array into parameter list:
console.log(...['spread', 'operator'])
Related
This question already has answers here:
TypeScript type signatures for functions with variable argument counts
(3 answers)
Closed last year.
I know theres probably an easy answer to this but I'm trying to create a function that resolves / returns the value of a variable amount of functions into an array. However it looks like typescript doesn't like this. What would be the appropriate way to write / fix this function
const func = (x:number, y:number) => {x,y}
const executeRepetitiveFunction = (num: number, func: () => unknown) => {
const returnValues: Array<(unknown)> = []
for (let i = 0; i < num; i++) {
returnValues.push(func())
}
return returnValues
}
error
var result = func();
^
TypeError: func is not a function
at executeRepetitiveFunction
If you want to return something from the function you are passing and store it in an array, you can just call it and declare func as a Function type.
You can do something like this:
const executeRepetitiveFunction = (num: number, func: Function) => {
const returnValues: Array<(unknown)> = []
for (let i = 0; i < num; i++) {
returnValues.push(func())
}
return returnValues
}
const testFunction: Function = (): String => {
return 'ok';
}
executeRepetitiveFunction(5, testFunction);
This will return ok 5 times and store it in an array . // Output: ['ok', 'ok', 'ok', 'ok', 'ok']
As someone said, your code doesn't make sense. The error you're seeing is completely accurate - you have no function defined called func. You have func set up as the name of a parameter in your executeRepetitiveFunction function declaration, but it's not available outside of that function's scope.
So that error is irrelevant to the question you're asking, and I'll just answer the question you're actually asking.
const executeRepetitiveFunction = (num: number, func: () => unknown) : Promise<Array<any>> => {
return new Promise((resolve, reject) => {
const returnValues: Array<any> = []
for (let i = 0; i < num; i++) {
returnValues.push(func())
}
resolve(returnValues);
});
}
const valuesPromise = executeRepetitiveFunction(5, () => {
return "Execution complete"
});
So what happens here? First we declare our executeRepetitiveFunction function, which takes two parameters, a number and a function which returns an unknown data type. Then we return a promise from this function, which resolves once the loop is complete.
We execute the function after it's declared, by calling the executeRepetitiveFunction function and passing it a number (5) and an anonymous function that simply returns a value.
Then when that's done, we can access our values by calling valuePromise.then(valuesArray => {console.log(valuesArray}); or handling it however else you want.
How are callback functions different from a helper function in javascript? if they are both accepting functions as arguments?
Callbacks are the functions that are passed as a function argument and are performed after a particular event such as resolving of a promise.
Helper functions are the normal functions that are called at any point of time when the code execution is taking place. Mostly, helper functions are wrapped inside another function.
Example of callback function:
const fun = (callback) => {
setTimeout(callback, 3000);
};
fun(() => {
console.log('callback function');
});
Example of helper function:
const factorialOfNNumbers = (...numbers) => {
const helperFact = (n) => {
if (n ===1 || n === 0)
return n;
return n * helperFact(n-1);
};
return numbers.map(n => helperFact(n));
};
console.log(factorialOfNNumbers(2, 3, 4));
They are both functions, but the difference I suppose is how they are referenced and/or used.
Helper functions are just called "whenever" when they are in scope. Callbacks are typically passed elsewhere and invoked with some parameters.
I hope the below snippet explains it.
// Just some function, what does it do?
const someFunction = (...args) => console.log("I'm a helper function", ...args);
const useAsHelperFunction = () => {
// Called directly
someFunction('used as helper function');
};
const useAsCallback = callback => {
// invoking callback
callback('used as callback function');
};
useAsHelperFunction();
useAsCallback(someFunction);
There nothing like callback function, it just refers to the function(named function) or anonymous function that is being called by a function or piece of code once it transitions to another state or after an event occurs.
Create a function defineFirstArg that accepts a function and an argument. Also, the function being passed in will accept at least one argument. defineFirstArg will return a new function that invokes the passed-in function with the passed-in argument as the passed-in function's first argument. Additional arguments needed by the passed-in function will need to be passed into the returned function.
Below is my code:
const defineFirstArg = (inputFunc, arg) => {
return function (argTwo) {
return inputFunc(arg, argTwo)
}
}
But it's failing the last test spec:
What am I doing wrong?
the third test condition says arguments, not an argument so maybe you will need to try spread operator instead
const defineFirstArg = (inputFunc, arg) => {
return function (...addtionalArgs) {
return inputFunc(arg, ...addtionalArgs)
}
}
f2 = defineFirstArg(console.log,"x")
f2("y","z",'f')
//x y z f
to spread the parameters and execute the function passed on an unlimited number of parameters
This is the code
const func0 = (...args) => {
console.error('-------0-------');
console.error(args);
console.error(args.length);
func1(args);
}
const func1 = (...args) => {
console.error('-------1-------');
console.error(args);
console.error(args.length);
}
func0(1, 2, 3);
why the 2nd arg is different now, how to make it the same as 1st one ?
(...args) => in the parameter list transforms the arguments into an array named args. So when you call func1(args);, you're calling func1 with one argument, an argument that's an array (whereas func0 was called with three arguments).
If you wanted to call func1 with the three original arguments, use spread to transform the args array into a parameter list:
const func0 = (...args) => {
console.error('-------0-------');
console.error(args);
console.error(args.length);
func1(...args);
}
const func1 = (...args) => {
console.error('-------1-------');
console.error(args);
console.error(args.length);
}
func0(1,2,3);
I have two files in a folder - index.js and util.js with their code base as follows
Util.js
let obj = {}
obj.sendTransaction = () => {
console.log(arguments);
return new Promise((resolve, reject) => {
// try {
// let data = ethFunction.call()
// resolve(data)
// } catch (e) {
// reject(e)
// }
});
}
module.exports = obj
In Index.js, if I pass arguments to addNewParticipant or its variation then they do not turn up in the arguments object in util.js, for instance
const addNewParticipant = (foo, bar) => {
var ethFunction = myContract.addParticipant.sendTransaction
console.log(ethFunction);
EthUtil.sendTransaction()
}
const addNewParticipantTwo = (foo, bar) => {
var ethFunction = myContract.addParticipant.sendTransaction
console.log(ethFunction);
EthUtil.sendTransaction(ethFunction, foo, bar)
}
and call it such addNewParticpant(1, 2) and , addNewParticpantNew(1, 2) the numbers 1 and 2 do not show up in the arguments object in the util function. In fact, the arguments object remains the same, 4 inputs describing some functions and files in node_modules including Bluebird and a reference to index.js itself
My final aim is to
Pass a function from index.js to util.js
Pass along unknown number of variables
Call the passed function and apply the unknown number of variables to it
Wrap the whole thing in a promise and do some data validation
Ideally arguments[0] would represent a function I would pass and the other would be the values. I would then use
var result = arguments[0].apply(null, Array().slice.call(arguments, 1));
If it helps, the function I want to pass has an optional callback feature
As already mentioned in the comment, fat arrows don't have their own this or arguments objects. The arguments object you're logging is from the function created by the module loader, and its passed arguments.
You can either use a "regular function", or in this case, you can use a ...rest parameter
And, avoid the Deferred antipattern.
//first a little utility that might be handy in different places:
//casts/converts a value to a promise,
//unlike Promise.resolve, passed functions are executed
var promise = function(value){
return typeof value === "function"?
this.then( value ):
Promise.resolve( value );
}.bind( Promise.resolve() );
module.exports = {
sendTransaction(fn, ...args){
return promise(() => fn.apply(null, args));
}
}