2015-10-20 24 views
5

Questo è un campo lungo, ma mi chiedevo se esiste qualcosa come C++ std :: bind in javascript o node.js? Ecco l'esempio in cui ho sentito la necessità di un vicolo cieco:Esiste un equivalente di std :: bind in javascript o 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(); 
    }); 
}); 

Invece di passare la richiamata a dbaccesss.exec, vorrei passare un puntatore a funzione che accetta un parametro. In C++ vorrei passare questo:

std::bind(writeResponse, res) 

Ciò si tradurrebbe in una funzione che prende un parametro (il 'risultato' nel mio caso), che ho potuto passare al posto della richiamata anonimo. In questo momento sto duplicando tutto il codice nella funzione anonima per ogni percorso nella mia app express.

+1

[Function.prototype.bind] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind)? – Oka

risposta

4

Mentre esiste, sarei più propenso a farlo con una chiusura:

function writeResponse(res) { 

    return function(result) { 
     res.write(JSON.stringify(result)); 
     res.end(); 
    }; 
} 
// and then... 
dbaccess.exec(query, writeResponse(res)); 
+0

Questo è grandioso, grazie. Lo trovo anche più leggibile rispetto all'uso di bind. – cocheci

-1

Esiste, ci sono due metodi. Call e apply che sono leggermente diversi.

Esiste anche un metodo bind, ma fa una cosa diversa (cambia il valore di this quando si chiama una funzione).

Non c'è una cosa come un 'puntatore a funzione' Penso che quello che vi serve qui è currying:

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

    return function() { 
    return fn.apply(that, args); 
    } 
} 
+0

Non sembra affatto quello che l'OP vuole. E puoi passare funzioni in JS, le funzioni sono oggetti e tutti gli oggetti vengono passati per riferimento. –

+0

"passa un puntatore a una funzione che accetta un parametro" mi suona come se volesse generare una funzione da una chiusura –

+0

@LuisSieira Sembra quasi che non comprenda _ veramente la terminologia corretta da utilizzare quando si descrivono le funzioni in JavaScript. – Oka

3

Se ho capito bene quello che stai cercando di fare, dovrei puntare al metodo Function.prototype.bind. Funziona come hai descritto:

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

In effetti è quello che stavo cercando, anche se sembra che dovresti passare 'undefined' piuttosto che' null'? – cocheci

+1

È più simile a una convenzione che a una regola, ma se stai passando l'oggetto nullo, stai dicendo che l'argomento dovrebbe essere "niente". – Microfed

1

Non sono sicuro se sono supportati in NodeJS ancora, ma se quindi, potresti anche utilizzare le funzioni freccia grossa abbastanza facilmente.

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

Essi hanno inoltre mantengono il valore lessicale this, che è bello quando è necessario.

E 'più o meno equivalente a questo:

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

anche se questo ha il this definito da .exec().

+0

Effettivamente anche questo funziona, grazie. – cocheci

3

Anche se un po 'diversa dalla funzione bind come si trova nel STL, è possibile utilizzare <function>.bind, che fa parte del prototipo di una funzione in JavaScript.

Il metodo bind restituisce un appena creata function oggetto (non dimenticate che function s sono primi cittadini in JavaScript e sono costruiti a partire dal Function prototipo) che accetta N meno M parametri (in JavaScript si tratta di una debole vincolo, infatti, accetta mai tanti parametri quanti ne passi, ma non ci sono garanzie che vengano utilizzati), dove N è il numero originale di parametri accettati, mentre M sono i limiti.

La differenza principale è che bind accetta anche come primo parametro una portata oggetto che sarà disponibile all'interno della stessa funzione appena creata come riferimento this, così si può letteralmente cambiare e iniettare il riferimento this durante l'esecuzione.

Here è possibile trovare la documentazione di bind.

Come accennato da qualcuno, si può anche contare su chiusure per ottenere il tuo obiettivo in quasi tutti i casi in cui è possibile utilizzare bind.

Problemi correlati