5

This is a long shot, but I was wondering if there is such a thing as the C++ std::bind in javascript or node.js? Here's the example where I felt the need for a bind:

var writeResponse = function(response, result) {
    response.write(JSON.stringify(result));
    response.end();
}


app.get('/sites', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    dbaccess.exec(query, function(result) {
        res.write(JSON.stringify(result));
        res.end();
    });
});

Instead of passing the callback to dbaccesss.exec, I would like to pass a function pointer that takes one parameter. In C++ I would pass this:

std::bind(writeResponse, res)

This would result in a function that takes one parameter (the 'result' in my case), which I could pass instead of the anonymous callback. Right now I am duplicating all that code in the anonymous function for every route in my express app.

cocheci
  • 375
  • 3
  • 7
  • 1
    [Function.prototype.bind](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind) ? – Oka Oct 20 '15 at 13:35

5 Answers5

4

If I understood well what you're trying to do, I ought to point to the Function.prototype.bind method. It works like you described:

app.get('/sites', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    dbaccess.exec(query, writeResponse.bind(null, res));
});
Microfed
  • 2,832
  • 22
  • 25
  • Indeed that's what I was looking for, although it looks like you should pass `undefined` rather than `null`? – cocheci Oct 20 '15 at 14:41
  • 1
    It's more like a convention rather than a rule, but if you're passing the null object, you're kind of saying: that argument should be 'nothing'. – Microfed Oct 20 '15 at 14:48
4

While it exists, I'd be more inclined to do it with a closure:

function writeResponse(res) {

    return function(result) {
        res.write(JSON.stringify(result));
        res.end();
    };
}
// and then...
dbaccess.exec(query, writeResponse(res));
chrisbajorin
  • 5,993
  • 3
  • 21
  • 34
4

Even though slightly different from the bind function as found in the STL, you can use <function>.bind, that is part of the prototype of a function in JavaScript.

The bind method returns a freshly created function object (do not forget that functions are first citizens in JavaScript and are built up starting from Function prototype) that accepts N minus M parameters (in JavaScript this is a weak constraint indeed, it will ever accept as many parameters as you pass it, but there are no guarantees that they will be used), where N is the original number of accepted parameters, while M are the bound ones.

The main difference is that bind accepts also as first argument a scope object which will be available from within the newly created function itself as the this reference, so you can literally change and inject the this reference during execution.

Here you can find the documentation of bind.

As mentioned by someone, you can also rely on closures to get your target in almost all the cases where you can use bind.

skypjack
  • 49,335
  • 19
  • 95
  • 187
1

Not sure if they're supported in NodeJS yet, but if so, you could also use fat arrow functions easily enough.

app.get('/sites', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    dbaccess.exec(query, r => writeResponse(res, r))
});

They also retain the lexical this value, which is nice when needed.

It's roughly equivalent to this:

app.get('/sites', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    dbaccess.exec(query, function(r) {
        return writeResponse(res, r);
    })
});

though this one has the this defined by .exec().

-1

It does exist, there are two methods. Call and apply which are slightly different.

There is a bind method as well, but it does a different thing (changes the value of this when calling a function).

There is not such a thing as a 'function pointer' I think what you need here is currying:

function currier(that, fn) {
  var args = [].slice.call(arguments, 2);

  return function() {
    return fn.apply(that, args);
  }
}
Luis Sieira
  • 29,926
  • 3
  • 31
  • 53
  • That doesn't seem to be what OP wants at all. And you can pass functions in JS, functions are objects and all objects are passed by reference. – Domino Oct 20 '15 at 13:41
  • "pass a function pointer that takes one parameter" sounds to me like he wants to generate a function from a closure – Luis Sieira Oct 20 '15 at 13:43
  • 1
    @LuisSieira It mostly sounds like they don't _really_ understand the proper terminology to use when describing functions in JavaScript. – Oka Oct 20 '15 at 13:44
  • Clearly, but what I understand from the question is "I want to pass a function as a parameter, that will be executed later with some argument that hasn't been generated yet". Here -> "This would result in a function that takes one parameter (the 'result' in my case), which I could pass instead of the anonymous callback" – Luis Sieira Oct 20 '15 at 13:46
  • 2
    You're missing out on the arguments passed to the function you're returning. You're going to need to join them with the bound `args`. –  Oct 20 '15 at 13:47