JavaScript: функция, возвращающая объект

90

Я беру уроки JavaScript / jQuery на codecademy.com. Обычно уроки дают ответы или подсказки, но в этом случае они не помогают, и меня немного смущают инструкции.

Он говорит, что функция makeGamePlayer должна возвращать объект с тремя ключами.

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

Я не уверен, должен ли я это делать

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

или что-то вроде этого

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

Я должен иметь возможность изменять свойства объекта после его создания.

МозгКакДуллКарандаш
источник

Ответы:

145

В JavaScript большинство функций являются как вызываемыми, так и экземплярами: у них есть внутренние методы [[Call]] и [[Construct]] .

Как вызываемые объекты, вы можете использовать круглые скобки для их вызова, при необходимости передавая некоторые аргументы. В результате вызова функция может вернуть значение .

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

Приведенный выше код вызывает функцию makeGamePlayerи сохраняет возвращаемое значение в переменной player. В этом случае вы можете определить функцию следующим образом:

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

Кроме того, когда вы вызываете функцию, вы также передаете дополнительный аргумент под капотом, который определяет значение thisвнутри функции. В приведенном выше случае, поскольку makeGamePlayerон не вызывается как метод, thisзначением будет глобальный объект в неаккуратном режиме или неопределенный в строгом режиме.

В качестве конструкторов вы можете использовать newоператор для их создания. Этот оператор использует внутренний метод [[Construct]] (доступный только в конструкторах), который делает что-то вроде этого:

  1. Создает новый объект, который наследуется от .prototypeконструктора
  2. Вызывает конструктор, передающий этот объект как thisзначение
  3. Он возвращает значение, возвращаемое конструктором, если это объект, или объект, созданный на шаге 1, в противном случае.
var player = new GamePlayer("John Smith", 15, 3);

Приведенный выше код создает экземпляр GamePlayerи сохраняет возвращаемое значение в переменной player. В этом случае вы можете определить функцию следующим образом:

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
}

По соглашению имена конструкторов начинаются с заглавной буквы.

Преимущество использования конструкторов заключается в том, что экземпляры наследуются от GamePlayer.prototype. Затем вы можете определить свойства там и сделать их доступными во всех экземплярах.

Ориол
источник
4
@OP также отметить , что , когда вы собираетесь вызвать его с newключевым словом , я предложил бы начать имя с большой буквы: MakeGamePlayer.
PeeHaa
3
@PeeHaa Хороший совет, также более типичным соглашением об именах при использовании конструктора было бы new GamePlayer().
Мэтт Зойнерт,
@RobG Спасибо, вот что происходит, когда я копирую код, не глядя на него глубоко.
Oriol
48

Вы можете просто сделать это с помощью литерала объекта :

function makeGamePlayer(name,totalScore,gamesPlayed) {
    return {
        name: name,
        totalscore: totalScore,
        gamesPlayed: gamesPlayed
    };
}
PeeHaa
источник
3
привет, как вы можете получить доступ к возвращаемым свойствам? Когда я использую makeGamePlayer.name, он не работает
iKamy
1
var player1 = makeGamePlayer («Бобби Фишер», 15, 5); player1.name;
mrturtle
5

Оба стиля, с небольшой доработкой, подойдут.

Первый метод использует конструктор Javascript, который, как и большинство других вещей, имеет свои плюсы и минусы.

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

С другой стороны, ваш другой метод называется «Выявление паттерна закрытия», если я правильно помню.

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

  return {
    name: name,
    age: age
  };
}
Джереми Дж. Старчер
источник
Это называется «раскрытие паттерна модуля», но обычно оно заключено в закрытое закрытие (function () {return {}}) ()
Фелипе Кирос
3

Последний способ сделать это с помощью ES2016 JavaScript

let makeGamePlayer = (name, totalScore, gamesPlayed) => ({
    name,
    totalScore,
    gamesPlayed
})
Роб
источник
2

Я бы сказал, что эти указания означают:

  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;
    }
сломанная кола
источник
1
Почему внутри объекта стоит точка с запятой?
Alex G
@AlexG хороший улов, не могу поверить, что никто другой не сделал этого за 4 года с тех пор, как я впервые опубликовал этот ответ. Несомненно, это была плохая работа по вырезанию и вставке исходного объекта OP, которую сделали я и, похоже, несколько других.
scrappedcola