JavaScript: функція, що повертає об'єкт


85

Я беру кілька уроків 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;
          }
    }

Я повинен мати можливість змінювати властивості об’єкта після його створення.

Відповіді:


143

У 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().
Matt Zeunert,

@RobG Дякую, саме це відбувається, коли я копіюю-вставляю код, не глибоко розглядаючи його.
Oriol

47

Ви можете просто зробити це таким чином за допомогою літералу об’єкта :

function makeGamePlayer(name,totalScore,gamesPlayed) {
    return {
        name: name,
        totalscore: totalScore,
        gamesPlayed: gamesPlayed
    };
}

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

Називається "виявляючий шаблон модуля", але він, як правило, загортається у приватне закриття (функція () {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 приємний улов, не можу повірити, що за чотири роки, як я вперше розмістив цю відповідь, цього не зробив ніхто. Це, безсумнівно, була погана вирізана-вставна робота оригінального об'єкта OP, яку я, і схоже, зробив кілька інших.
скрапкола
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.