Search code examples
javascriptlinked-listsingly-linked-list

Creating a Linked List in Javascript using Factory functions


I'm trying to make a Linked list using factory functions. The defined functions inside it (like append and prepend) seem to be working fine. But they are not changing the default value of my head, tail, and size. Here's the code snippet:

const Node = (data = null, next = null) => {
    return {data, next}
}

const LinkedList = () => {
    let head = null;
    let tail = null;
    let length = 0;
    
    // append(value) adds a new node containing value to the end of the list
    const append = (value) => {
        const newTailNode = Node(value);
        if(!head){
            return prepend(value)
        }else{
            let current = head;
            while(current.next){
                current = current.next;
            }
            current.next = newTailNode;
            tail = newTailNode;
            length++;
            return tail
        }
    }
    // prepend(value) adds a new node containing value to the start of the list
    const prepend = (value) => {
        // const newHeadNode = Node(value, head)
        // head = newHeadNode;
        // return newHeadNode
        head = Node(value, head)
        length++;
        return {head, length}
    }
    
    // size returns the total number of nodes in the list
    const size = () => {
        return length
    }
    
    
    return {prepend, append, size,}
};

const l = LinkedList()
l.prepend(55)
l.prepend(44)
l.prepend(33)
l.append(66)
l.append(77)
console.log(l.head)

If I console.log(l.prepend(33)) it's returns {head: {data: 33, next: {data: 44, next: {data: 55, next: null}}}, length: 3}, which is absolutely fine. But if I console.log(l.head)after all these appendings and prependings, it returns null even though the head has been changed to 33 since l.prepend(33). Obviously I expect the functions to change the default value of the head, tail, and length.


Solution

  • Your l object does hot have a head property. It has a head local variable, which cannot be accessed as a property.

    The easiest way to solve this, is to have LinkedList return a (getter) method for retrieving the current head, much like you do for size:

        // Return a head getter:
        return {prepend, append, size, get head() { return head }};
    

    With that change the code will work. I would also make append and prepend void functions. Their return value is then less interesting. It is even not consistent in your implementation, because append only returns the new node, while prepend returns both the new node (head) and current length. So that means a call to append will return an object with a different interface on the first call than any subsequent calls. Anyway, the length can be retrieved via l.size() so you don't need it to come back from prepend, and returning the newly created node may not be all that useful anyway.