Basic JavaScript Design Patterns — Factories, Iterators, and Decorators
Tags: architecture, webdev, programming, javascript
Published: 2021-01-30 21:27:21

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


JavaScript lets us do a lot of things. It’s sometimes too forgiving in its syntax.

To organize our code, we should use some basic design patterns. In the article, we’ll look at factories, iterators, and decorators.

### Built-in Object Factory

JavaScript’s standard library comes with several factory methods.

They include `Object` , `Boolean` , `Number` , `String` , and `Array` .

For instance, we can use the `Boolean` factory function as follows:

```
const bool = Boolean(1);
```

Then `bool` is `true` since 1 is truthy.

All they do is return different objects or values according to what we pass in.

Many of them are useful. However, the `Object` constructor isn’t all that useful since we can create objects with object literals.

### Iterator

JavaScript has iterators since ES6.

Therefore, we don’t have to write anything from scratch to implement this pattern

We just have to use a generator function to return the values we’re looking for sequentially.

Then we can call the built-in `next` function to get the value returned after the generator is returned from the generator function.

For instance, we can write:

```
const numGen = function*() {
  while (true) {
    yield (Math.random() * 100).toFixed(1);
  }
}
```

to create a generator function.

A generator function is denoted by the `function*` keyword. There’s an asterisk after the `function` keyword.

The `yield` keyword will return the next value sequentially.

Then we can use it to return a random number as follows:

```
const nums = numGen();
console.log(nums.next().value);
console.log(nums.next().value);
console.log(nums.next().value);
```

We first call `numGen` to return an iterator.

Then we call `nums.next().value` to get the values we want.

We can also have a generator function that returns a finite number of values.

For instance, we can write:

```
const numGen = function*() {
  const arr = [1, 2, 3];
  for (const a of arr) {
    yield a;
  }
}

const nums = numGen();
let value = nums.next().value;
while (value) {
  console.log(value);
  value = nums.next().value;
}
```

In the code above, we changed the `numGen` function to return an array’s entries in sequence.

This way, we can call the `next` method in a loop to get the entries in sequence with the `next` method.

In addition to `value` property, the object returned by the `next` method also has the `done` property.

So we can write:

```
const nums = numGen();
let {
  done,
  value
} = nums.next();

while (!done) {
  console.log(value);
  const next = nums.next();
  done = next.done;
  value = next.value;
}
```

Once all the values are returned, `done` will be set to `true`.

### Additional Functionality

If we want more functionality, then we’ve to implement our own iterator.

For instance, if we want rewind functionality, we can create our own iterator as follows:

```
const iterator = (() => {
  const arr = [1, 2, 3];
  let index = 0;
  return {
    next() {
      index++;
      return arr[index];
    },
    rewind() {
      index--;
      return arr[index];
    }
  }
})();
```

We just added an array with the `next` method to move to the next `arr` entry and `rewind` to move to the previous `arr` entry.

Then we can use `iterator` as follows:

```
console.log(iterator.next());
console.log(iterator.rewind());
```

And we see:

```
2
1
```

from the console log output.

### Decorator

Decorators let us add functionality to an object on the fly.

JavaScript has decorators now so that we can use them to create our own decorator and mutate objects on the fly.

For instance, we can create one as follows:

```
const foo = () => {
  return (target, name, descriptor) => {
    descriptor.value = "foo";
    return descriptor;
  };
};

class Foo {
  @foo()
  bar() {
    return "baz";
  }
}

const f = new Foo();
console.log(f.bar);
```

A decorator in JavaScript, it’s just a function that returns a function with the parameters `target` , `name` and `descriptor` .

`descriptor` is the property descriptor, so we can set the `value` , `writable` , and `enumerable` properties for it.

Our `foo` decorator transformed the `value` property of it to the string `'foo'` .

So we get that `Foo` instance’s `bar` property becomes the string `'foo'` instead of a method.

JavaScript decorators are still experimental syntax, so we need Babel to use it.

### Conclusion

JavaScript has various factory functions that let us create objects.

There’s the `Object` , `Boolean` , `Number` , `String` functions and more.

JavaScript has built-in support for iterators. However, if we want more functionality that it provides, then we’ve to implement our own.

Decorators exist in JavaScript, so we can use it to create decorators to modify properties.