1

I am trying to use the factory function way of implementing an object, and tried it with a linked list example, where I initialize an empty linked list then try to add nodes, in the add method method I set the head if it is not set, otherwise add the node to the last node in the chain. The problem is that the head never appears to get set, any ideas why?

"use strict"

const niceLog = s =>  {
  console.log(JSON.stringify(s, null, 2))
}

function linkedList() {
  let head

  const node = data => {
    return {
      data,
      next: null
    }
  }

  const add = data => {
    if (!head) {
      head = node(data)
    } else {
      const end = node(data)
      let n = head
      while (n.next) n = n.next
      n.next = end
    }
  }

  const del = data => {
    let n = head

    if (n.data === data) head = head.next

    while (n.next) {
      if (n.next.data === data) {
        n.next = n.next.next
        return
      }
      n = n.next
    }
  }


  return {
    head,
    add,
    del
  }
}


const ll = linkedList()

ll.add('cheese')
ll.add('crackers')
ll.add('tea')
ll.add('coffee')

niceLog(ll) // {}

Here is the equivalent code in es6 class syntax which does work, (I had heard that factory functions are better as they avoid the issues of new and this keywords not being set properly so thats why I was trying to use factory functions)

const niceLog = s =>  {
  console.log(JSON.stringify(s, null, 2))
}

class Node {
  constructor(data) {
    this.data = data
    this.next = null
  }
}

class LinkedList {
  constructor() {
    this.head = null
  }

  add(data){
    if (!this.head) {
      this.head = new Node(data)
    } else {
      const end = new Node(data)
      let n = this.head
      while (n.next) n = n.next
      n.next = end
    }
  }

  del(data) {
    let n = this.head

    if (n.data === data) this.head = this.head.next

    while (n.next) {
      if (n.next.data === data) {
        n.next = n.next.next
        return
      }
      n = n.next
    }
  }
}


const ll = new LinkedList()

ll.add('cheese')
ll.add('crackers')
ll.add('tea')
ll.add('coffee')

niceLog(ll) // output = 


"head": {
    "data": "cheese",
    "next": {
      "data": "crackers",
      "next": {
        "data": "tea",
        "next": {
          "data": "coffee",
          "next": null
        }
      }
    }
  }
}
2
  • 2
    So...what's your question? Commented Jul 25, 2016 at 20:10
  • I added the question part now! Commented Jul 25, 2016 at 20:26

1 Answer 1

2

This is too long for a comment. You seem confused as to what a 'factory function' is in JavaScript. A factory function does not mean you avoid the this keyword. It does mean that you avoid the new keyword:

let myFactoryPrototype = {
  someMethod: function() {
    return this.foo;
  }
};

let myFactory = () => Object.create(myFactoryPrototype);
let myObject = myFactory(); // no 'new'

Note the mix of regular and arrow function syntax. I've used arrow functions where this doesn't matter, and regular old function where it does. If you want to avoid this then don't use methods, use regular (possibly pure) functions that operate on data types:

const addToLinkedList = (list, node) => {
  // code return a new list with the extra node goes here
};

But really, avoiding this is difficult in JavaScript, you're really cutting against the grain. Avoiding new on the other hand is quite easy, just use Object.create or object literals.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.