简体   繁体   中英

Is there an equivalent of std::bind in javascript or node.js?

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.

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));

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));
});

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 function s 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 .

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() .

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);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM