84 lines
1.6 KiB
Markdown
84 lines
1.6 KiB
Markdown
---
|
|
stage: none
|
|
group: unassigned
|
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
|
---
|
|
|
|
# Design Patterns
|
|
|
|
## Singletons
|
|
|
|
When exactly one object is needed for a given task, prefer to define it as a
|
|
`class` rather than as an object literal. Prefer also to explicitly restrict
|
|
instantiation, unless flexibility is important (e.g. for testing).
|
|
|
|
```javascript
|
|
// bad
|
|
|
|
const MyThing = {
|
|
prop1: 'hello',
|
|
method1: () => {}
|
|
};
|
|
|
|
export default MyThing;
|
|
|
|
// good
|
|
|
|
class MyThing {
|
|
constructor() {
|
|
this.prop1 = 'hello';
|
|
}
|
|
method1() {}
|
|
}
|
|
|
|
export default new MyThing();
|
|
|
|
// best
|
|
|
|
export default class MyThing {
|
|
constructor() {
|
|
if (!MyThing.prototype.singleton) {
|
|
this.init();
|
|
MyThing.prototype.singleton = this;
|
|
}
|
|
return MyThing.prototype.singleton;
|
|
}
|
|
|
|
init() {
|
|
this.prop1 = 'hello';
|
|
}
|
|
|
|
method1() {}
|
|
}
|
|
|
|
```
|
|
|
|
## Manipulating the DOM in a JS Class
|
|
|
|
When writing a class that needs to manipulate the DOM guarantee a container option is provided.
|
|
This is useful when we need that class to be instantiated more than once in the same page.
|
|
|
|
Bad:
|
|
|
|
```javascript
|
|
class Foo {
|
|
constructor() {
|
|
document.querySelector('.bar');
|
|
}
|
|
}
|
|
new Foo();
|
|
```
|
|
|
|
Good:
|
|
|
|
```javascript
|
|
class Foo {
|
|
constructor(opts) {
|
|
document.querySelector(`${opts.container} .bar`);
|
|
}
|
|
}
|
|
|
|
new Foo({ container: '.my-element' });
|
|
```
|
|
|
|
You can find an example of the above in this [class](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/javascripts/mini_pipeline_graph_dropdown.js);
|