JavaScript: função que retorna um objeto

90

Estou tendo algumas aulas de JavaScript / jQuery em codecademy.com. Normalmente as aulas fornecem respostas ou dicas, mas para esta não ajuda em nada e fico um pouco confuso com as instruções.

Diz para fazer com que a função makeGamePlayer retorne um objeto com três chaves.

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

Não tenho certeza se deveria estar fazendo isso

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

ou algo parecido com isto

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

Tenho que ser capaz de modificar as propriedades do objeto após sua criação.

BrainLikeADullPencil
fonte

Respostas:

145

Em JavaScript, a maioria das funções pode ser chamada e instanciada: elas têm métodos internos [[Call]] e [[Construct]] .

Como objetos chamáveis, você pode usar parênteses para chamá-los, passando opcionalmente alguns argumentos. Como resultado da chamada, a função pode retornar um valor .

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

O código acima chama a função makeGamePlayere armazena o valor retornado na variável player. Nesse caso, você pode definir a função assim:

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

Além disso, quando você chama uma função, você também está passando um argumento adicional sob o capô, que determina o valor de thisdentro da função. No caso acima, desdemakeGamePlayer não é chamado como método, othis valor será o objeto global em modo descuidado, ou indefinido em modo estrito.

Como construtores, você pode usar o newoperador para instanciá-los. Este operador usa o método interno [[Construct]] (disponível apenas em construtores), que faz algo assim:

  1. Cria um novo objeto que herda do .prototype de do construtor
  2. Chama o construtor passando este objeto como o this valor
  3. Ele retorna o valor retornado pelo construtor se for um objeto, ou o objeto criado na etapa 1 caso contrário.
var player = new GamePlayer("John Smith", 15, 3);

O código acima cria uma instância de GamePlayere armazena o valor retornado na variável player. Nesse caso, você pode definir a função assim:

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 convenção, os nomes dos construtores começam com uma letra maiúscula.

A vantagem de usar construtores é que as instâncias são herdadas de GamePlayer.prototype. Em seguida, você pode definir propriedades lá e torná-las disponíveis em todas as instâncias

Oriol
fonte
4
@OP também notar que quando você está indo para invocá-lo com a newpalavra-chave que eu sugeriria começar o nome com um capital: MakeGamePlayer.
PeeHaa
3
@PeeHaa Bom conselho, também seria a convenção de nomenclatura mais típica ao usar o construtor new GamePlayer().
Matt Zeunert
@RobG Obrigado, isso é o que acontece quando copio e colo o código sem examiná-lo profundamente.
Oriol
48

Você pode simplesmente fazer assim com um literal de objeto :

function makeGamePlayer(name,totalScore,gamesPlayed) {
    return {
        name: name,
        totalscore: totalScore,
        gamesPlayed: gamesPlayed
    };
}
PeeHaa
fonte
3
Olá, como você pode acessar as propriedades de retorno, quando eu uso makeGamePlayer.name ele não funciona
iKamy
1
var player1 = makeGamePlayer ("Bobby Fischer", 15, 5); player1.name;
mrturtle de
5

Ambos os estilos, com um toque de ajustes, funcionariam.

O primeiro método usa um Construtor Javascript, que como a maioria das coisas tem prós e 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 outro lado, seu outro método é chamado de 'Padrão de Fechamento Revelador', se bem me lembro.

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

  return {
    name: name,
    age: age
  };
}
Jeremy J Starcher
fonte
É chamado de "padrão de módulo revelador", mas geralmente é encerrado em private closure (function () {return {}}) ()
Felipe Quirós
3

A forma mais recente de fazer isso com ES2016 JavaScript

let makeGamePlayer = (name, totalScore, gamesPlayed) => ({
    name,
    totalScore,
    gamesPlayed
})
Roubar
fonte
2

Eu interpretaria essas instruções como significando:

  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;
    }
scrappedcola
fonte
1
Por que você tem ponto e vírgula dentro do objeto?
Alex G
@AlexG nice catch, não posso acreditar que ninguém fez nos 4 anos desde que eu postei esta resposta pela primeira vez. Sem dúvida, foi um trabalho ruim de recortar e colar do objeto original do OP que eu e parece que alguns outros criamos.
scrappedcola