JavaScript: función que devuelve un objeto

85

Estoy tomando algunas lecciones de JavaScript / jQuery en codecademy.com. Normalmente las lecciones brindan respuestas o sugerencias, pero para esta no brindan ninguna ayuda y estoy un poco confundido por las instrucciones.

Dice que la función makeGamePlayer devuelva un objeto con tres claves.

//First, the object creator
function makeGamePlayer(name,totalScore,gamesPlayed) {
    //should return an object with three keys:
    // name
    // totalScore
    // gamesPlayed
}

No estoy seguro si debería estar haciendo esto

//First, the object creator
function makeGamePlayer(name,totalScore,gamesPlayed) {
    //should return an object with three keys:
    // name
    // totalScore
    // gamesPlayed

         this.name =  name;
         this.totalScore = totalScore;
         this.gamesPlayed = gamesPlayed;
}

o algo como esto

 //First, the object creator
    function makeGamePlayer(name,totalScore,gamesPlayed) {
        //should return an object with three keys:
        // name
        // totalScore
        // gamesPlayed

         var obj = {
             this.name =  name;
             this.totalScore = totalScore;
             this.gamesPlayed = gamesPlayed;
          }
    }

Tengo que poder modificar las propiedades del objeto después de su creación.

BrainLikeADullLápiz
fuente

Respuestas:

143

En JavaScript, la mayoría de las funciones son tanto invocables como instanciables: tienen métodos internos [[Call]] y [[Construct]] .

Como objetos invocables, puede usar paréntesis para llamarlos, pasando opcionalmente algunos argumentos. Como resultado de la llamada, la función puede devolver un valor .

var player = makeGamePlayer("John Smith", 15, 3);

El código anterior llama a la función makeGamePlayery almacena el valor devuelto en la variable player. En este caso, es posible que desee definir la función de esta manera:

function makeGamePlayer(name, totalScore, gamesPlayed) {
  // Define desired object
  var obj = {
    name:  name,
    totalScore: totalScore,
    gamesPlayed: gamesPlayed
  };
  // Return it
  return obj;
}

Además, cuando llama a una función, también está pasando un argumento adicional bajo el capó, que determina el valor de thisdentro de la función. En el caso anterior, dado makeGamePlayerque no se llama como método, el thisvalor será el objeto global en modo descuidado o indefinido en modo estricto.

Como constructores, puede utilizar el newoperador para instanciarlos. Este operador usa el método interno [[Construct]] (solo disponible en constructores), que hace algo como esto:

  1. Crea un nuevo objeto que hereda del .prototypedel constructor
  2. Llama al constructor pasando este objeto como thisvalor
  3. Devuelve el valor devuelto por el constructor si es un objeto, o el objeto creado en el paso 1 en caso contrario.
var player = new GamePlayer("John Smith", 15, 3);

El código anterior crea una instancia GamePlayery almacena el valor devuelto en la variable player. En este caso, es posible que desee definir la función de esta manera:

function GamePlayer(name,totalScore,gamesPlayed) {
  // `this` is the instance which is currently being created
  this.name =  name;
  this.totalScore = totalScore;
  this.gamesPlayed = gamesPlayed;
  // No need to return, but you can use `return this;` if you want
}

Por convención, los nombres de los constructores comienzan con una letra mayúscula.

La ventaja de utilizar constructores es que las instancias heredan de GamePlayer.prototype. Luego, puede definir propiedades allí y hacerlas disponibles en todos los casos.

Oriol
fuente
4
@OP en cuenta también que cuando se va a invocar con la newpalabra clave Me permito sugerir a partir del nombre con mayúscula: MakeGamePlayer.
PeeHaa
3
@PeeHaa Buen consejo, también sería la convención de nomenclatura más típica cuando se usa el constructor new GamePlayer().
Matt Zeunert
@RobG Gracias, eso es lo que sucede cuando copio y pego un código sin mirarlo profundamente.
Oriol
47

Simplemente puede hacerlo así con un objeto literal :

function makeGamePlayer(name,totalScore,gamesPlayed) {
    return {
        name: name,
        totalscore: totalScore,
        gamesPlayed: gamesPlayed
    };
}
PeeHaa
fuente
3
hola, ¿cómo se puede acceder a las propiedades de devolución? Cuando uso makeGamePlayer.name no funciona
iKamy
1
var player1 = makeGamePlayer ("Bobby Fischer", 15, 5); player1.name;
mrturtle
5

Ambos estilos, con un toque de retoque, funcionarían.

El primer método usa un constructor de Javascript, que como la mayoría de las cosas tiene pros y contras.

 // By convention, constructors start with an upper case letter
function MakePerson(name,age) {
  // The magic variable 'this' is set by the Javascript engine and points to a newly created object that is ours.
  this.name = name;
  this.age = age;
  this.occupation = "Hobo";
}
var jeremy = new MakePerson("Jeremy", 800);

Por otro lado, su otro método se llama 'Patrón de cierre revelador' si no recuerdo mal.

function makePerson(name2, age2) {
  var name = name2;
  var age = age2;

  return {
    name: name,
    age: age
  };
}
Jeremy J Starcher
fuente
Se llama "patrón de módulo revelador" Pero generalmente está envuelto en un cierre privado (function () {return {}}) ()
Felipe Quirós
3

La última forma de hacer esto con ES2016 JavaScript

let makeGamePlayer = (name, totalScore, gamesPlayed) => ({
    name,
    totalScore,
    gamesPlayed
})
Robar
fuente
2

Yo tomaría esas direcciones en el sentido de:

  function makeGamePlayer(name,totalScore,gamesPlayed) {
        //should return an object with three keys:
        // name
        // totalScore
        // gamesPlayed

         var obj = {  //note you don't use = in an object definition
             "name": name,
             "totalScore": totalScore,
             "gamesPlayed": gamesPlayed
          }
         return obj;
    }
cola de pescado
fuente
1
¿Por qué tiene punto y coma dentro del objeto?
Alex G
@AlexG buena captura, no puedo creer que nadie más lo haya hecho en los 4 años desde que publiqué esta respuesta por primera vez. Sin duda, fue un mal trabajo de cortar y pegar del objeto original del OP que yo y algunos otros hicieron.
Scrappedcola