admin管理员组

文章数量:1314008

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.

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.

Share Improve this question asked Oct 20, 2015 at 13:30 cochecicocheci 3753 silver badges7 bronze badges 1
  • 1 Function.prototype.bind ? – Oka Commented Oct 20, 2015 at 13:35
Add a ment  | 

5 Answers 5

Reset to default 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));

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

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

本文标签: Is there an equivalent of stdbind in javascript or nodejsStack Overflow