The code that I am practicing with is where I have a function called InReverse. This function accepts a function as an argument and returns a function. When the function returned is invoked, it reverses the order of the arguments.
When the returned functions are returned:
const catDog = ('cat', 'dog') => returns ('dog cat')
What I have rewritten out so far is:
function inReverse (func) {
return function (...arguments) {
return arguments.map((element) => {
element.reverse();
});
}
}
Any guidance would be appreciated!
You need to simply call the input function inside the newly created anonymous function.
For example this works:
function inReverse(f) {
return function () {
let args = [...arguments].reverse();
return f.apply(this, args);
}
}
So for example if you have subtract function like this:
function subtract(a, b) {
return a-b;
}
subtract(1, 10); will be -9 as expected.
and inReverse(subtract)(1, 10) will be 9 as expected.
Not sure why you're using map, just call reverse right on the arguments array. Also you weren't calling func:
function inReverse(func) {
return function(...args) {
return func(...args.reverse());
};
}
(Notice that arguments is a reserved identifier in strict mode, you should name your parameter for something else)
Not sure, why you are using map method, just use reverse method in your function right on the arguments. Reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse?retiredLocale=id
Just reverse the arguments, and use func.apply(this, arr)
function inReverse(func) {
return function() {
var args = Array.prototype.slice.call(arguments)
args = args.reverse();
return func.apply(this, args);
}
}
function div(a, b) {
return a / b
}
console.log(div(1, 2))
console.log(inReverse(div)(1, 2))
This question already has answers here:
Passing a function with parameters as a parameter?
(7 answers)
Closed 3 years ago.
I'm new to javascript and I was learning higher-order functions where I learned about passing functions as arguments to other functions. How can I pass a function with arguments to a function?
I want to pass the function's arguments when passing the function as parameter to the main function.
example :
function fubar(a,b,fun(c,d)){
//execute here
}
and not like this
function fubar(a,b,fun()){
fun(a,b)
}
Here's an example, just pass it like a regular argument, no specific syntax is required :)
// define the function argument like a regular argument
function fubar(a, b, fn){
// call that argument like a function
return fn(a, b);
}
// sample function
function add(c, d){
return c + d;
}
// pass the "add" function like a regular argument
let result = fubar(1, 2, add);
console.log(result);
You just need to pass the name of the function as the parameter, just like another variable.
for example :
foobar(5, 10, baz, ham);
function foobar(a, b, fn1, fn2){
...
fn1(); // call the baz function.
res = fn2(a,b); // calls ham func with a and b as parameter
console.log(res)
...
}
function baz(){
console.log("Inside the Baz function ");
}
function ham(s,t){
console.log(s, t);
return s+t;
}
If you're asking how to pass a function that will execute with some pre-determined arguments, you can do so using another function.
For example
const a = 'a'
const b = 'b'
const c = 'c'
const d = 'd'
function fubar(a, b, fn) {
console.info('func:', a, b, fn()) // executing "fn()" here
}
function fun(arg1, arg2) {
console.info('fun:', arg1, arg2)
return 'return value from fun' // just an example so you can see it in fubar()
}
fubar(a, b, () => fun(c, d))
Here, () => fun(c, d) is an self-contained, anonymous arrow function (or "lambda") that when called, will execute fun(c, d).
Is it possible inside list to get all available functions - a, b, c without their enumeration and without using window?
(function(){
function a() { return 1; }
function b() { return 2; }
function c() { return 3; }
function list()
{
return [a, b, c];
}
})();
No, it's not possible with functions declared directly in the current scope.
To achieve this, you would have to assign the functions to some property of the scope, i.e.:
(function() {
let funcs = {};
funcs.a = function() {
return 1;
}
...
function list() {
return Object.values(funcs);
}
});
NB: Object.values is ES7, in ES6 use:
return Object.keys(funcs).map(k => funcs[k]);
or in ES2015 or earlier use:
return Object.keys(funcs).map(function(k) { return funcs[k] });
If you haven't even got Object.keys, give up... ;)
I understand where you are trying to get. So perhaps this is the closest thing to what you requested, without using the window name (the same object though):
// define a non-anonymous function in the global scope
// this function contains all the functions you need to enumerate
function non_anon() {
function a() { return 1; }
function b() { return 2; }
function c() { return 3; }
function list() { return [a, b, c]; }
// you need to return your `list` function
// i.e. the one that aggregates all the functions in this scope
return list;
}
// since in here the purpose is to access the global object,
// instead of using the `window` name, you may use `this`
for (var gobj in this) {
// from the global scope print only the objects that matter to you
switch (gobj) {
case 'non_anon':
console.info(gobj, typeof this.gobj);
console.log(
// since you need to execute the function you just found
// together with the function returned by its scope (in order to `list`)
// concatenate its name to a double pair of `()` and...
eval(gobj + '()()') // evil wins
);
break;
}
}
I'm learning JavaScript and am trying to learn the proper terms for what I am doing. There are so many ways to create a function.
I have created 3 examples that do the same thing, but the functions are created in completely different ways.
My questions are:
Are any one of these methods better than the other?
Why would I choose to do one way or another?
What is the last "object" method called?
What advice would you have to make this example better?
//EXAMPLE 1
// is this called function declaration?
function add( a, b ) {
return a + b;
}
function subtract( a, b ) {
return a - b;
}
function compute( a, b ) {
var sum = add( a, b );
var difference = subtract( a, b );
var total = sum + difference;
return total;
}
compute( 2, 3 ); //returns 4
//EXAMPLE 2
// is this called function expressions?
var add = function ( a, b ) {
return a + b;
};
var subtract = function ( a, b ) {
return a - b;
};
var compute = function ( a, b ) {
var sum = add( a, b );
var difference = subtract( a, b );
var total = sum + difference;
return total;
};
compute( 2, 3 ); //returns 4
//EXAMPLE 3
// what is this method called?
var calculator = {
add: function ( a, b ) {
return a + b;
},
subtract: function ( a, b ) {
return a - b;
},
compute: function ( a, b ) {
var sum = this.add( a, b );
var difference = this.subtract( a, b );
var total = sum + difference;
return total;
}
}
calculator.compute( 2, 3 ); //returns 4
is this called function declaration?
function add( a, b ) {
return a + b;
}
Yes.
is this called function expressions?
var add = function ( a, b ) {
return a + b;
};
Yes. Notice that only the function(…){…} part is the function expression, the rest is a normal assignment (variable declaration with initialiser, to be pedantic).
what is this method called?
… {
add: function ( a, b ) {
return a + b;
},
…
}
Again, it's a function expression. Used as a property value in an object literal here, to define a method.
Are any one of these methods better than the other?
Function declarations are preferred over assigning function expressions to variables (there are slight differences). You should use expressions only where you need them as an expression (e.g. in IIFEs, conditional assignments, property assignments, property definitions, return statements etc).
Function declaration:
function add(a,b) { return a+b; }
A function declaration is defined at parse time for a certain script block. It can be called anywhere in the block without producing an error:
(function() {
add(3,3) //The function block has already been parsed, add() is available
function add(a,b) { return a+b; }
})();
Function expressions:
var add = function(a,b) { return a+b; }
Function expressions assign a variable to an anonymous function. These are evaluated at run time and cannot be called before being declared.
(function() {
add(3,3) //Error: add() has not yet been defined.
var add = function(a,b) { return a+b; }
})();
Object Methods:
Methods, are functions that are a property of an object.
var obj = {
propert1: 'property1 value',
add: function(a,b) {
return a+b;
}
};
These may be called via obj.add(3,3), however not prior to declaring the object via an object literal or assignment of a method to a property.
Is there a preffered way?
Declaring functions via a function declaration offers flexibility. It may however lead to unexpected results, For example(raised functions):
(function returnVal() {
function getSomething() {
return 'foo';
}
return getSomething();
function getSomething() {
return 'bar';
}
})(); //returns 'bar'
The return of the function may appear unexpected, however functions are raised during parse-time, and getSomething() is overridden.
Rewriting the code using a function expression produces the desired result
(function returnVal() {
var getSomething = function() {
return 'foo';
}
return getSomething();
getSomething = function() {
return 'bar';
}
})(); //returns 'foo'
Object methods on the other hand act much like function expressions however they are accessible under the object's name.
var obj = {};
obj.foo = function() { /*code*/ }
obj.bar = function() { /*code*/ }
They act similarly to function expressions, however this groups code under the ownership of obj. For clarity you may wish to choose this.
In Javascript, how can I bind arguments to a function without binding the this parameter?
For example:
//Example function.
var c = function(a, b, c, callback) {};
//Bind values 1, 2, and 3 to a, b, and c, leave callback unbound.
var b = c.bind(null, 1, 2, 3); //How can I do this without binding scope?
How can I avoid the side-effect of having to bind the function's scope (e.g. setting this = null) as well?
Edit:
Sorry for the confusion. I want to bind arguments, then be able to call the bound function later and have it behave exactly as if I called the original function and passed it the bound arguments:
var x = 'outside object';
var obj = {
x: 'inside object',
c: function(a, b, c, callback) {
console.log(this.x);
}
};
var b = obj.c.bind(null, 1, 2, 3);
//These should both have exact same output.
obj.c(1, 2, 3, function(){});
b(function(){});
//The following works, but I was hoping there was a better way:
var b = obj.c.bind(obj, 1, 2, 3); //Anyway to make it work without typing obj twice?
I'm still new at this, sorry for the confusion.
Thanks!
You can do this, but best to avoid thinking of it as "binding" since that is the term used for setting the "this" value. Perhaps think of it as "wrapping" the arguments into a function?
What you do is create a function that has the desired arguments built into it via closures:
var withWrappedArguments = function(arg1, arg2)
{
return function() { ... do your stuff with arg1 and arg2 ... };
}(actualArg1Value, actualArg2Value);
Hope I got the syntax right there. What it does is create a function called withWrappedArguments() (to be pedantic it is an anonymous function assigned to the variable) that you can call any time any where and will always act with actualArg1Value and actualArg2Value, and anything else you want to put in there. You can also have it accept further arguments at the time of the call if you want. The secret is the parentheses after the final closing brace. These cause the outer function to be immediately executed, with the passed values, and to generate the inner function that can be called later. The passed values are then frozen at the time the function is generated.
This is effectively what bind does, but this way it is explicit that the wrapped arguments are simply closures on local variables, and there is no need to change the behaviour of this.
In ES6, this is easily done using rest parameters in conjunction with the spread operator.
So we can define a function bindArgs that works like bind, except that only arguments are bound, but not the context (this).
Function.prototype.bindArgs =
function (...boundArgs)
{
const targetFunction = this;
return function (...args) { return targetFunction.call(this, ...boundArgs, ...args); };
};
Then, for a specified function foo and an object obj, the statement
return foo.call(obj, 1, 2, 3, 4);
is equivalent to
let bar = foo.bindArgs(1, 2);
return bar.call(obj, 3, 4);
where only the first and second arguments are bound to bar, while the context obj specified in the invocation is used and extra arguments are appended after the bound arguments. The return value is simply forwarded.
In the native bind method the this value in the result function is lost. However, you can easily recode the common shim not to use an argument for the context:
Function.prototype.arg = function() {
if (typeof this !== "function")
throw new TypeError("Function.prototype.arg needs to be called on a function");
var slice = Array.prototype.slice,
args = slice.call(arguments),
fn = this,
partial = function() {
return fn.apply(this, args.concat(slice.call(arguments)));
// ^^^^
};
partial.prototype = Object.create(this.prototype);
return partial;
};
var b = function() {
return c(1,2,3);
};
One more tiny implementation just for fun:
function bindWithoutThis(cb) {
var bindArgs = Array.prototype.slice.call(arguments, 1);
return function () {
var internalArgs = Array.prototype.slice.call(arguments, 0);
var args = Array.prototype.concat(bindArgs, internalArgs);
return cb.apply(this, args);
};
}
How to use:
function onWriteEnd(evt) {}
var myPersonalWriteEnd = bindWithoutThis(onWriteEnd, "some", "data");
It's a bit hard to tell exactly what you ultimately want to do because the example is sort of arbitrary, but you may want to look into partials (or currying): http://jsbin.com/ifoqoj/1/edit
Function.prototype.partial = function(){
var fn = this, args = Array.prototype.slice.call(arguments);
return function(){
var arg = 0;
for ( var i = 0; i < args.length && arg < arguments.length; i++ )
if ( args[i] === undefined )
args[i] = arguments[arg++];
return fn.apply(this, args);
};
};
var c = function(a, b, c, callback) {
console.log( a, b, c, callback )
};
var b = c.partial(1, 2, 3, undefined);
b(function(){})
Link to John Resig's article: http://ejohn.org/blog/partial-functions-in-javascript/
Using LoDash you can use the _.partial function.
const f = function (a, b, c, callback) {}
const pf = _.partial(f, 1, 2, 3) // f has first 3 arguments bound.
pf(function () {}) // callback.
May be you want to bind reference of this in last but your code:-
var c = function(a, b, c, callback) {};
var b = c.bind(null, 1, 2, 3);
Already applied binding for instance this and later you can not change it.
What I will suggest that use reference also as a parameter like this:-
var c = function(a, b, c, callback, ref) {
var self = this ? this : ref;
// Now you can use self just like this in your code
};
var b = c.bind(null, 1, 2, 3),
newRef = this, // or ref whatever you want to apply inside function c()
d = c.bind(callback, newRef);
Use a protagonist!
var geoOpts = {...};
function geoSuccess(user){ // protagonizes for 'user'
return function Success(pos){
if(!pos || !pos.coords || !pos.coords.latitude || !pos.coords.longitude){ throw new Error('Geolocation Error: insufficient data.'); }
var data = {pos.coords: pos.coords, ...};
// now we have a callback we can turn into an object. implementation can use 'this' inside callback
if(user){
user.prototype = data;
user.prototype.watch = watchUser;
thus.User = (new user(data));
console.log('thus.User', thus, thus.User);
}
}
}
function geoError(errorCallback){ // protagonizes for 'errorCallback'
return function(err){
console.log('#DECLINED', err);
errorCallback && errorCallback(err);
}
}
function getUserPos(user, error, opts){
nav.geo.getPos(geoSuccess(user), geoError(error), opts || geoOpts);
}
Basically, the function you want to pass params to becomes a proxy which you can call to pass a variable, and it returns the function you actually want to do stuff.
Hope this helps!
An anonymous user posted this additional info:
Building on what has already been provided in this post -- the most elegant solution I've seen is to Curry your arguments and context:
function Class(a, b, c, d){
console.log('#Class #this', this, a, b, c, d);
}
function Context(name){
console.log('#Context', this, name);
this.name = name;
}
var context1 = new Context('One');
var context2 = new Context('Two');
function curryArguments(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function bindContext() {
var additional = Array.prototype.slice.call(arguments, 0);
return fn.apply(this, args.concat(additional));
};
}
var bindContext = curryArguments(Class, 'A', 'B');
bindContext.apply(context1, ['C', 'D']);
bindContext.apply(context2, ['Y', 'Z']);
Well for the exemple you gave, this will do
var b= function(callback){
return obj.c(1,2,3, callback);
};
If you want to guarenty enclosure of the parameters :
var b= (function(p1,p2,p3, obj){
var c=obj.c;
return function(callback){
return c.call(obj,p1,p2,p3, callback);
}
})(1,2,3,obj)
But if so you should just stick to your solution:
var b = obj.c.bind(obj, 1, 2, 3);
It's the better way.
Simple like that?
var b = (cb) => obj.c(1,2,3, cb)
b(function(){}) // insidde object
More general solution:
function original(a, b, c) { console.log(a, b, c) }
let tied = (...args) => original(1, 2, ...args)
original(1,2,3) // 1 2 3
tied(5,6,7) // 1 2 5
I'm using this function:
function bindArgs(func, ...boundArgs) {
return function (...args) {
return func(...boundArgs, ...args);
};
}
// use
const deleteGroup = bindArgs(this.props.deleteGroup, "gorupName1");
Why not use a wrapper around the function to save this as mythis ?
function mythis() {
this.name = "mythis";
mythis = this;
function c(a, b) {
this.name = "original";
alert('a=' + a + ' b =' + b + 'this = ' + this.name + ' mythis = ' + mythis.name);
return "ok";
}
return {
c: c
}
};
var retval = mythis().c(0, 1);
jQuery 1.9 brought exactly that feature with the proxy function.
As of jQuery 1.9, when the context is null or undefined the proxied function will be called with the same this object as the proxy was called with. This allows $.proxy() to be used to partially apply the arguments of a function without changing the context.
Example:
$.proxy(this.myFunction,
undefined /* leaving the context empty */,
[precededArg1, precededArg2]);
Jquery use case:
instead:
for(var i = 0;i<3;i++){
$('<input>').appendTo('body').click(function(i){
$(this).val(i); // wont work, because 'this' becomes 'i'
}.bind(i));
}
use this:
for(var i = 0;i<3;i++){
$('<input>').appendTo('body').click(function(e){
var i = this;
$(e.originalEvent.target).val(i);
}.bind(i));
}