如何在不使用类的情况下使用暴露方法创建对象实例化?

时间:2019-01-16 23:55:53

标签: javascript methods javascript-objects

我有一个任务要解决,但有一定的局限性。这是任务:

创建一个对象Shape来实例化一个新Shape,该对象将根据组成该形状的段的数量向控制台输出文本。 Shape对象具有一个存储该值的属性“类型”,可以通过其showType()函数对其进行访问。

默认属性类型值为3。

Shape有几种方法:

Describe()

行为:

  • 如果类型数严格小于3,则null.undefined或未定义的Shape.describe()应将其设置为3,同时“ console.log”消息: “形状需要至少具有3个线段,它将被设置为3”,同时将线段属性值设置为3。
  • 如果类型的数量等于3,则Shape.describe()应该“ console.log”消息: “您创建的Shape是一个由3个线段组成的三角形”,同时将type属性值设置为3。
  • 如果类型的数量等于4,则Shape.describe()应该“ console.log”消息: “您创建的Shape是由4个线段组成的四边形”,同时将线段属性值设置为4。
  • 如果段数等于5,则Shape.describe()应该“ console.log”消息: “您创建的Shape是一个由5个线段组成的五边形”,同时将线段属性值设置为5。
  • 如果段数等于3,Shape.describe()应该“ console.log”消息: “您创建的Shape是一个由6个线段组成的六边形”,同时将线段属性值设置为6。
  • 如果类型的数量大于6,则Shape.describe()应该“ console.log”消息: “您创建的形状是由{number_bigger_than_six}个线段组成的通用形状”,同时将线段属性值设置为{number_bigger_than_six}。

Increase()

行为:

  • Shape.increase()应该增加对象属性类型的值,并同时使用Shape.describe()记录相应的消息

示例:

const square = getShape(4)//->将type属性设置为4 Shape.describe()//-> console.log('您创建的Shape是由4个线段组成的四边形') Shape.increase()//-> console.log('您创建的Shape是一个由5个线段组成的五边形'),同时增加了正方形对象的type属性。

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 :(得分:0)

您应该

const result = {
    showType:  function() {

因此您可以进行getShape().showType()
这是您要问的吗?

答案 1 :(得分:0)

Object Composition

对象组合是根据对象和原始数据类型(布尔值,字符串,数字等)创建对象。您想要避免使用类,但希望对象之间共享方法,那么您是正确的-工厂函数将是可行的解。该术语称为串联继承-composing objects by extending an existing object with new properties

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>

答案 2 :(得分:0)

据我从作业要求中了解,它测试了您对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();