Как создать экземпляр объекта с помощью методов, не используя классы? - PullRequest
0 голосов
/ 17 января 2019

У меня есть задача, с определенными ограничениями. Это задача:

Создание объекта Shape для создания экземпляра нового Shape, который будет выводить на консоль текст в зависимости от количества сегментов, из которых состоит форма. У объекта Shape есть одно свойство «type», в котором хранится это значение, и к нему можно получить доступ через функцию showType ().

По умолчанию значение типа свойства равно 3.

Форма имеет несколько методов:

Опишите ()

поведение:

  • Если число типов строго меньше 3, то null или undefined Shape.describe () должен установить для них значение 3 и одновременно «console.log» сообщение: «У фигуры должно быть как минимум 3 сегмента, для нее будет установлено значение 3», и в то же время значение свойства сегментов должно быть равно 3.
  • Если число типов равно 3, Shape.describe () должно "console.log" сообщение: «Созданная вами фигура представляет собой треугольник, состоящий из 3 сегментов», и в то же время задайте для свойства type значение 3.
  • Если число типов равно 4, Shape.describe () должно "console.log" сообщение: «Форма, которую вы создали, представляет собой четырехугольник, состоящий из 4 сегментов», и в то же время установите значение свойства сегмента равным 4.
  • Если количество сегментов равно 5, Shape.describe () должно «console.log» вывести сообщение: «Созданная вами фигура представляет собой пятиугольник, состоящий из 5 сегментов», и в то же время установите значение свойства сегмента равным 5.
  • Если количество сегментов равно 3, Shape.describe () должно «console.log» сообщение: «Созданная вами фигура представляет собой шестиугольник, состоящий из 6 сегментов», и в то же время установите значение свойства сегмента равным 6.
  • Если число типов больше 6, Shape.describe () должен «console.log» вывести сообщение: «Созданная вами форма является общей формой, составленной из {number_bigger_than_six} сегментов», и в то же время установите значение свойства сегмента в {number_bigger_than_six}.

Увеличение ()

поведение:

  • Shape.increase () должен увеличивать значение типа свойства объекта и одновременно регистрировать соответствующее сообщение с помощью Shape.describe ()

пример:

const square = getShape (4) // -> устанавливает свойство типа в 4 Shape.describe () // -> console.log («Созданная вами форма представляет собой четырехугольник, состоящий из 4 сегментов») Shape.increase () // -> console.log («Созданная вами фигура представляет собой пятиугольник, состоящий из 5 сегментов») и одновременно свойство приращения типа квадратного объекта.

Whatis ()

поведение:

Shape.whatIs () // -> Открыть новое окно браузера, которое ссылается на https://en.wikipedia.org/wiki/Polygon

Код по умолчанию, который необходимо использовать для этой задачи:

const getShape = function (countOfTypes) {
  // Create a Shape Object

  const result = {
    showType() {
      // Return (Number) the current count of types
      return Number (segments);
    },
    describe() {
      // log 'The shape you created is a *** composed by * 
segments'

    },
    increase() {
      // Increase the type property of a created shape by 1 and 
log the appropriate sentence in describe()      
    },
    whatIs() {
      // Open a new window that links to 
 https://en.wikipedia.org/wiki/Polygon

    }
  };
  return result;
};

//Test and use Cases

const square = getShape(4);
square.describe(); // The shape you created is a quadrilateral 
composed by 4 segments
square.increase() // The shape you created is a pentagon composed 
by 5 segments

const generic = getShape(18);
generic.describe(); // The shape you created is a generic shape 
composed by 18 segments

generic.whatIs(); // Open a new window that links to 
https://en.wikipedia.org/wiki/Polygon


const emptyShape = getShape(); // Emit a log message: 'A shape 
needs to have at least 3 segments, it will be set to 3' and set it 
to 3

Это абсолютно необходимо решить с помощью существующего кода, который ограничивает нас от использования классов. Я привык решать подобные вещи с помощью классов, поэтому я попытался склониться к большему, чтобы сбить с толку тему фабричных функций.

Я пытаюсь найти рабочее решение здесь, но я не эксперт в этом вопросе, и вроде как потерян.

Я пытаюсь сделать что-то подобное.

const getShape = function (countOfTypes) {
  // Create a Shape Object
  return {
    type: result.showType()
  }

  const result = {
    showType() {
      // Return (Number) the current count of types

      return Number (countOfTypes);
    },
    describe(countOfTypes) {
      // log 'The shape you created is a *** composed by * segments'
      if (!countOfTypes || countOfTypes < 3) {  
        console.log ('A shape need to have at least 3 segments. It 
will be set to 3.')
        result.showType(3);
      }
      if (countOfTypes > 6){
        console.log("The shape you created is a generic shape 
composed by " + countOfTypes + " types")
      }

      if (countOfTypes == 3 || countOfTypes == 4 || countOfTypes == 
5 || countOfTypes == 6) {
        console.log ('The Shape you created is ' + segmentName + ' 
created from ' + this.type + ' segments.')
      }

      let names = ['triangle', 'quadrilateral', 'pentagon', ' 
hexagon']
      segmentName = names[countOfTypes - 3];

    },
    increase() {
      // Increase the type property of a created shape and log the 
same sentence in describe()
      Number(countOfTypes) + 1;
      console.log ('The Shape you created is ' + segmentName + ' 
created from ' + this.type + ' segments.')       
    },
    whatIs() {
      // Open a new window that links to 
https://en.wikipedia.org/wiki/Polygon
      window.open('https://en.wikipedia.org/wiki/Polygon');
    }
  };
  return result;
};

//Test and use cases

const square = getShape(4);
square.describe(); // The shape you created is a quadrilateral 
composed by 4 segments
square.increase() // The Shape you created is a pentagon composed 
by 5 segments

const generic = getShape(18);
generic.describe(); // The Shape you created is a generic Shape 
composed by 18 segments

generic.whatIs(); // Open a new window that links to 
https://en.wikipedia.org/wiki/Polygon

const emptyShape = getShape(); // Emit a log message: 'A Shape needs 
to have at least 3 segments, it will be set to 3' and set it to 3     

Если честно, я немного застрял, и получение этого результата не является определенной ошибкой, любая помощь в решении этой проблемы будет принята с благодарностью.

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Состав объекта

Композиция объектов создает объекты из объектных и примитивных типов данных (логические значения, строки, числа и т. Д.). Вы хотите избегать использования классов, но хотите использовать общие методы для объектов, тогда вы правы - фабричная функция была бы жизнеспособной решение. Этот термин называется конкатенативным наследованием - составление объектов путем расширения существующего объекта новыми свойствами :

Object.assign(properties, method(properties), ...)

Я не могу писать в рамках вашего домашнего задания, надеюсь, это направит вас в правильном направлении. Следующая демка получит от 3 до 20 от пользователя, создаст объект и из свойств этого объекта сгенерирует HTML с именем многоугольника, а также ссылку и изображение указанного многоугольника. Я оставляю вам описание.


Plunker

Демо

Подробности прокомментированы в демоверсии

<!DOCTYPE html>
<html>

<head>
  <style>
    form {
      font: 400 16px/1.25 Consolas
    }
    
    input,
    output,
    button {
      display: inline-block;
      font: inherit
    }
    
    input {
      text-align: center;
    }
    
    img {
      display: block;
      margin: 0 auto;
      height: 250px;
      width: auto;
    }
  </style>
</head>

<body>
  <form id='poly' onsubmit='return false'>
    <fieldset>
      <legend>Regular Polygons</legend>
      <label> Sides: </label>
      <input id='qty' type='number' min='3' max='20'>
      <button id='btn'>GO</button>
    </fieldset>
    <fieldset id='view'></fieldset>
  </form>
  <script>
    /* Composite Objects */
    /*
    getType has the name() method which will convert props.sides into the 
    proper index of the types array to get the correct value for prop.type
    */
    const getType = (props, types) => ({
      name: () => {
        props.type = types[props.sides - 3];
      }
    });

    /*
    getLinx has the link() and image() methods props.type is used by the former 
    and props.sides and the dir array are used by the later to interpolate 
    strings into template literals that become urls for props.url and props.img.
    */
    const getLinx = (props, dir) => ({
      link: () => {
        props.url = `https://en.wikipedia.org/wiki/${props.type}`;
      },
      image: () => {
        switch (props.sides) {
          case 4:
            props.img = `https://upload.wikimedia.org/wikipedia/commons/3/3d/Six_Quadrilaterals.svg`;
            break;
          default:
            props.img = `https://upload.wikimedia.org/wikipedia/commons/${dir[props.sides - 3]}/Regular_polygon_${props.sides}_annotated.svg`;
            break;
        }
      }
    });
    /*
    polygon() function factory passes 2 parameters sides (Number) and tag 
    (String) props is the object that will have the three methods name(), link(), 
    and image() by concatenative inheritance using Object.assign().
    */
    const polygon = (sides, tag) => {
      const types = ["Triangle", "Quadrilateral", "Pentagon", "Hexagon", "Septagon", "Octogon", "Nonagon", "Decagon", "Undecagon", "Dodecagon", "Tridecagon", "Tetradecagon", "Pentadecagon", "Hexadecagon", "Heptadecagon", "Octadecagon", "Enneadecagon", "Icosagon"];
      const dir = ["e/eb", "3/3d", "0/01", "3/38", "7/75", "e/e5", "b/ba", "b/b9", "f/f8", "0/06", "a/a6", "e/e1", "d/d0", "e/e4", "c/c6", "d/d8", "1/18", "2/23"];
      let props = {
        tag: tag,
        sides: sides,
        type: '',
        url: '',
        img: '',
        desc: ''
      };
      return Object.assign(props, getType(props, types), getLinx(props, dir));
    };

    /* DOM Interface */
    /* 
    HTMLFormControlsCollection is a terse API that references tags by id or name
    */
    const poly = document.forms.poly;
    const qty = poly.qty;
    const view = poly.view;

    /*
    #btn is regustered to the click event. When triggered, the value of #qty 
    (.valueAsNumber) and the number of #view's chid elements (.childElementCount)
    become arguments for the function displayPoly().
    */
    poly.btn.addEventListener('click', (e) => {
      const vert = qty.valueAsNumber;
      const count = view.childElementCount;
      displayPoly(vert, count);
    });

    /* 
    displayPoly() passes the number from #qty and interpolates the number #view
    with a generic word to create a unique string to pass it to polygon() as the
    2nd argument. Next, the object creayed by polygon is returned and referenced
    as shape. shape's methods are invoked and then the new values are generated.
    The values of type, url, and img are interpolated into a string which is then
    rendered as HTML and prepended to #view.
    */
    const displayPoly = (number, index) => {
      let name = `shape${index}`;
      let shape = polygon(number, name);
      shape.name();
      shape.link();
      shape.image();
      let Type = shape.type;
      let Url = shape.url;
      let Img = shape.img;
      let item = `
  <figure id='${name}'>
    <figcaption title='${shape.sides} Sides'>${Type}</figcaption>
    <a href='${Url}'>
      <img src='${Img}'>
    </a>
  </figure>
  `;
      view.insertAdjacentHTML('afterbegin', item);
      return false;
    };
  </script>
</body>

</html>
0 голосов
/ 17 января 2019

Насколько я понимаю из требований к домашней работе, это проверяет ваше понимание JavaScript Closures .

Вот как можно использовать крышки для решения:

Во-первых, данный базовый код уже возвращает объект результата. Возвращаемый объект результата предоставляет методы, которые можно вызвать извне: showType(), describe(), increase(), whatIs(). То, что вы пишете внутри этих функций, имеет доступ к области действия getShape().

Я создал переменную с именем segments и функцию с именем getName() внутри функции getShape(). Как видите, они могут быть доступны только внутри функции getShape().

Вот полный код ниже:

const getShape = function (countOfTypes = 3) {
  // Create a Shape Object
  let segments = countOfTypes;

  function getName() {
    if (segments < 3) {
      return null;
    } else if (segments === 3) {
      return "triangle";
    } else if (segments === 4) {
      return "quadrilateral";
    } // vice versa
  }

  const result = {
    showType() {
      // Return (Number) the current count of types
      return Number (segments);
    },
    describe() {
      // log 'The shape you created is a *** composed by * segments
      if (getName() === null) {
        console.log("A shape needs to have at least 3 segments, it will be set to 3, and set the type property value to 3");
      } else {
        console.log(`The shape you created is a ${getName()} composed by ${segments} segments`);
      }
    },
    increase() {
      // Increase the type property of a created shape by 1 and log the appropriate sentence in describe()
      segments++;
      result.describe();
    },
    whatIs() {
      // Open a new window that links to https://en.wikipedia.org/wiki/Polygon
      window.open("https://en.wikipedia.org/wiki/Polygon");
    }
  };
  return result;
};

//Test and use Cases

const square = getShape(3);
square.describe();
square.increase();
0 голосов
/ 17 января 2019

Вы должны сделать

const result = {
    showType:  function() {

Так что вы можете сделать getShape().showType().
Это то, что вы спрашиваете?

...