Función que modifica un argumento, ¿debo devolver el objeto modificado?

7

Tenemos una función que modifica un objeto JS, agregándole algunas propiedades personalizadas. La función no devuelve antyhing

addTransaction: function (obj) {
     obj.transactionId = this.getTransactionId;
     obj.id = this.recordId;
},

Alguien dijo que prefería que addTransaction devolviera obj .

Esto es lo que pensé

  • Si no devuelvo nada (y documento que el objeto se va a modificar), es bastante claro que el objeto se va a modificar, como si el nombre fuera addTransactionToObj

  • Si quiero agregar un valor de retorno, no debo modificar el objeto entrante, debo clonar el objeto dado, agregar mis propiedades al clon y devolver el clon.

  • Tener un valor de retorno que solo devuelve uno de los parámetros (modificados) simplemente suena mal

¿Alguien tiene alguna preferencia en este asunto?

    
pregunta Juan Mendes 10.04.2013 - 20:12

4 respuestas

4

Le permite hacer encadenamiento de métodos , que mucha gente cree que mejora la legibilidad. Es un muy modismo común en JavaScript, lo que significa que mucha gente lo espera, especialmente si el resto de la base del código es similar. Su segundo punto sobre la clonación del objeto también tiene mérito, si se usa para hacer que su objeto sea inmutable . Lo beneficioso que es depende de su aplicación específica.

    
respondido por el Karl Bielefeldt 10.04.2013 - 20:35
2

En primer lugar, creo que esta función es extraña ... quiero decir que esperaba que addTransaction agregara una transacción a this , no al revés. Pero tal vez sea solo yo (edición: aparentemente no). Si esto es realmente lo que quieres hacer, entonces sugiero leer "nombrando tu función".

En segundo lugar, creo que el problema principal se encuentra en la parte "agregar" de "addTransaction". Para mí, significa que un objeto será modificado para tener una "transacción".

En tercer lugar, hay varias formas de hacerlo. Usted puede:

  • devolver una copia, lo que significa que su objeto original es inmutable
  • devuelva el objeto al que se adjunta la transacción, por lo que está siguiendo el paradigma de interfaz fluida .
  • no devolver nada, el objeto se modifica

No hay una "mejor" manera, solo sé coherente y KISS al elegir una aplicación determinada.

Nombrando tu función

Robert C. Martin en ( Consejos sobre el código de limpieza en funciones de nombres ) indica que cuanto más pequeño Cuanto más preciso sea el nombre de la función, más alcance. Sugiero nombrarlo como algo a lo largo de las líneas de " attachTransactionIdAndRecordIdToObject " si desea mantener ambos configuradores en la misma función. Una vez más, ya sea que el usuario devuelva el objeto o no, es su elección.

    
respondido por el Jalayn 10.04.2013 - 20:40
1
  

Si no devuelvo nada, queda claro que el objeto se modificará

No necesariamente. Podría ser un método que cause efectos secundarios, como un registrador.

  

Si quiero agregar un valor de retorno, no debo modificar el objeto entrante, debo clonar el objeto dado, agregar mis propiedades al clon y devolver el clon.

En general, estoy de acuerdo con eso. Pero devolver el objeto original es una técnica válida, especialmente si está creando una Interfaz fluida .

Como señala Florian, un mejor enfoque podría ser agregar la función al objeto en sí, como en DoSomethingToThis() .

    
respondido por el Robert Harvey 10.04.2013 - 20:34
0

Se me ocurrió algo tratando de incorporar todas las sugerencias. Haga una clase del objeto que va a enviar con la solicitud AJAX.

function MyAjaxParams() {  
    this.obj = {};
}

/**
 * @param {MyDocument} doc
 */
MyAjaxParams.prototype.addTransaction = function(doc) {
     this.transactionId = doc.getTransactionId();
     this.id = this.getRecordId();
}

MyAjaxParams.prototype.getParamsObject = function() {
    return this.obj;
}

// Many other methods to insert all required AJAX parameters

Entonces mi código existente haría lo siguiente

MyDocument.prototype.save = function () {
    var ajaxParams = new MyAjaxParams();
    ajaxParams.addTransactionParams(this);
    ...
    Ext.Ajax.request.send({
      url: '/here/we/go',
      params: ajaxParams.getParamsObject()
    });
}
    
respondido por el Juan Mendes 10.04.2013 - 20:56

Lea otras preguntas en las etiquetas