JavaScript: funkcja zwracająca obiekt

85

Biorę lekcje JavaScript / jQuery na codecademy.com. Zwykle lekcje dostarczają odpowiedzi lub podpowiedzi, ale w tej nie pomagają i jestem trochę zdezorientowany instrukcjami.

Mówi, aby funkcja makeGamePlayer zwracała obiekt z trzema kluczami.

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

Nie jestem pewien, czy powinienem to robić

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

lub coś w tym stylu

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

Muszę mieć możliwość modyfikowania właściwości obiektu po jego utworzeniu.

BrainLikeADullPencil
źródło

Odpowiedzi:

143

W JavaScript większość funkcji jest zarówno wywoływalnych, jak i instancyjnych: mają one zarówno wewnętrzne metody [[Call]], jak i [[Construct]] .

Jako obiekty wywoływalne, możesz użyć nawiasów, aby je wywołać, opcjonalnie przekazując niektóre argumenty. W wyniku wywołania funkcja może zwrócić wartość .

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

Powyższy kod wywołuje funkcję makeGamePlayeri przechowuje zwróconą wartość w zmiennej player. W takim przypadku możesz chcieć zdefiniować funkcję w ten sposób:

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

Dodatkowo, gdy wywołujesz funkcję, przekazujesz również dodatkowy argument pod maską, który określa wartość thiswewnątrz funkcji. W powyższym przypadku, ponieważ makeGamePlayernie jest wywoływana jako metoda, thiswartością będzie obiekt globalny w trybie niechlujnym lub niezdefiniowany w trybie ścisłym.

Jako konstruktorzy możesz użyć newoperatora do ich wystąpienia. Ten operator używa metody wewnętrznej [[Construct]] (dostępnej tylko w konstruktorach), która robi coś takiego:

  1. Tworzy nowy obiekt, który dziedziczy z .prototypekonstruktora
  2. Wywołuje konstruktora przekazującego ten obiekt jako thiswartość
  3. Zwraca wartość zwróconą przez konstruktora, jeśli jest to obiekt, lub obiekt utworzony w kroku 1 w przeciwnym razie.
var player = new GamePlayer("John Smith", 15, 3);

Powyższy kod tworzy wystąpienie GamePlayeri przechowuje zwróconą wartość w zmiennej player. W takim przypadku możesz chcieć zdefiniować funkcję w ten sposób:

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
}

Zgodnie z konwencją nazwy konstruktorów zaczynają się od dużej litery.

Zaletą korzystania z konstruktorów jest to, że wystąpienia dziedziczą po GamePlayer.prototype. Następnie możesz zdefiniować tam właściwości i udostępnić je we wszystkich wystąpieniach

Oriol
źródło
4
@OP pamiętać również, że kiedy idziesz do wywołania go z newkluczowych Proponuję rozpoczęcie nazwę z kapitałem: MakeGamePlayer.
PeeHaa
3
@PeeHaa Dobra rada, również bardziej typowa konwencja nazewnictwa przy korzystaniu z konstruktora new GamePlayer().
Matt Zeunert,
@RobG Dzięki, tak właśnie się dzieje, gdy kopiuję i wklejam kod bez dokładniejszej jego analizy.
Oriol
47

Możesz to po prostu zrobić w ten sposób za pomocą dosłownego obiektu :

function makeGamePlayer(name,totalScore,gamesPlayed) {
    return {
        name: name,
        totalscore: totalScore,
        gamesPlayed: gamesPlayed
    };
}
PeeHaa
źródło
3
witam, jak możesz uzyskać dostęp do właściwości zwracanych, kiedy używam makeGamePlayer.name to nie działa
iKamy
1
var player1 = makeGamePlayer ("Bobby Fischer", 15, 5); player1.name;
mrturtle
5

Oba style, z odrobiną poprawiania, będą działać.

Pierwsza metoda wykorzystuje konstruktor JavaScript, który jak większość rzeczy ma zalety i wady.

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

Z drugiej strony, jeśli dobrze pamiętam, twoja druga metoda nazywa się „ujawniającym wzorcem zamknięcia”.

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

  return {
    name: name,
    age: age
  };
}
Jeremy J Starcher
źródło
Nazywa się „ujawniającym wzorcem modułu”, ale zwykle jest opakowany w prywatne zamknięcie (function () {return {}}) ()
Felipe Quirós
3

Najnowszy sposób na to dzięki JavaScriptowi ES2016

let makeGamePlayer = (name, totalScore, gamesPlayed) => ({
    name,
    totalScore,
    gamesPlayed
})
Obrabować
źródło
2

Uznałbym te wskazówki za oznaczające:

  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;
    }
złomowana cola
źródło
1
Dlaczego wewnątrz obiektu znajdują się średniki?
Alex G
@AlexG niezły chwyt, nie mogę uwierzyć, że nikt inny tego nie zrobił w ciągu 4 lat, odkąd po raz pierwszy opublikowałem tę odpowiedź. Niewątpliwie było to złe zadanie wycinania i wklejania oryginalnego obiektu OP, który ja i wygląda na to, że zrobiliśmy kilka innych.
scrappedcola