1.0.0 • Published 5 years ago

@joelnet/deconstruct v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 years ago

deconstruct

For those that prefer using Functions over Classes.

Install

npm i https://github.com/joelnet/deconstruct.git

Usage

Given a Class:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }

  getFullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

Pass your Class to deconstruct. Use destructuring to access the constructor and any methods attached to the Class.

// deconstruct and destructure the Person Class
const { constructor: createPerson, getFullName } = deconstruct(Person)

// create a new Person
const person = createPerson('Akira', 'Kurosawa')
//=> { firstName: 'Akira', lastName: 'Kurosawa' }

// call the getFullName function with our person
const fullName = getFullName(person)
//=> "Akira Kurosawa"

Benefits

  • No more problems with this being assigned to something else.

  • Functions can be used by other parts of the application, not just the Class.

  • Encourages composition over inheritance.

Caveats

This cannot be used with code that relies on instanceof. Because the deconstructed objects are Plain Old JavaScript Objects, instanceof will always be Object.

ES5 Classes

Works the same with ES5 Classes

function Person() {
  this.firstName = firstName
  this.lastName = lastName
}

Person.prototype.getFullName = function getFullName() {
  return `${this.firstName} ${this.lastName}`
}

// deconstruct and destructure the Person Class
const { constructor: createPerson, getFullName } = deconstruct(Person)

Static Methods

Static methods are already functions, just use them.

class Person {
  static getType() {
    return 'Person'
  }
}

Person.getType()
//=> 'Person'

Ideas

Export Functions not Classes

have more control over how your Classes are used. Export Functions and not the Class.

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName
    this.lastName = lastName
  }

  getFullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

// deconstruct and destructure the Person Class
const { constructor: createPerson, getFullName } = deconstruct(Person)

module.exports = {
  createPerson,
  getFullName
}

Prevent this bugs

Typical this bug:

// destructuring changes the `this` context.
const logFullName = ({ getFullName }) => console.log(`fullname: ${getFullName()}`)

const person = new Person('Akira', 'Kurosawa')
logFullName(person)
//=> Cannot read property 'firstName' of undefined

Instead write:

// no more bugs with `this`
const logFullName = context => console.log(`fullname: ${getFullName(context)}`)

const person = createPerson('Akira', 'Kurosawa')
logFullName(person)
//=> fullname: Akira Kurosawa