Есть ли эквивалент std::bind в javascript или node.js?
Это долгий путь, но мне было интересно, есть ли такая вещь, как C++ std::bind в javascript или node.js? Вот пример, где я чувствовал потребность в привязке:
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();
});
});
Вместо передачи обратного вызова в dbaccesss.exec, я хотел бы передать указатель на функцию, которая принимает один параметр. В C++ я бы передал это:
std::bind(writeResponse, res)
Это привело бы к функции, которая принимает один параметр ("результат" в моем случае), который я мог бы передать вместо анонимного обратного вызова. Прямо сейчас я дублирую весь этот код в анонимной функции для каждого маршрута в моем экспресс-приложении.
5 ответов
Пока он существует, я бы более склонен сделать это с закрытием:
function writeResponse(res) {
return function(result) {
res.write(JSON.stringify(result));
res.end();
};
}
// and then...
dbaccess.exec(query, writeResponse(res));
Если я хорошо понимаю, что вы пытаетесь сделать, я должен указать на метод Function.prototype.bind. Это работает как вы описали:
app.get('/sites', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
dbaccess.exec(query, writeResponse.bind(null, res));
});
Хотя немного отличается от bind
функция, как найдено в STL
, ты можешь использовать <function>.bind
, это часть прототипа функции в JavaScript.
bind
метод возвращает только что созданный function
объект (не забывайте, что function
s являются первыми гражданами в JavaScript и создаются начиная с Function
прототип), который принимает N минус M параметров (в JavaScript это действительно слабое ограничение, он всегда будет принимать столько параметров, сколько вы его передадите, но нет никаких гарантий, что они будут использованы), где N - исходное число принятых параметры, а М - связанные.
Основное отличие состоит в том, что bind
принимает также в качестве первого аргумента объект области видимости, который будет доступен из вновь созданной функции как this
ссылка, так что вы можете буквально изменить и ввести this
ссылка во время исполнения.
Здесь вы можете найти документацию bind
,
Как уже упоминалось, вы также можете положиться на замыкания, чтобы получить свою цель почти во всех случаях, когда вы можете использовать связывание.
Не уверен, что они поддерживаются в NodeJS, но если это так, вы также можете достаточно легко использовать функции жирной стрелки.
app.get('/sites', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
dbaccess.exec(query, r => writeResponse(res, r))
});
Они также сохраняют лексическое this
значение, которое приятно, когда это необходимо.
Это примерно эквивалентно этому:
app.get('/sites', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
dbaccess.exec(query, function(r) {
return writeResponse(res, r);
})
});
хотя этот имеет this
определяется .exec()
,
Это существует, есть два метода. Позвоните и подайте заявку, которые немного отличаются.
Существует также метод связывания, но он выполняет другое действие (изменяет значение this
при вызове функции).
Не существует такого понятия, как "указатель на функцию", я думаю, что здесь вам нужно каррирование:
function currier(that, fn) {
var args = [].slice.call(arguments, 2);
return function() {
return fn.apply(that, args);
}
}