add(data) {
    
        /*
         * Create a new list node object and store the data in it.
         * This node will be added to the end of the existing list.
         */
        const newNode = new DoublyLinkedListNode(data);
                
        // special case: no nodes in the list yet
        if (this[head] === null) {

            /*
             * Because there are no nodes in the list, just set the
             * `this[head]` pointer to the new node.
             */
            this[head] = newNode;
        } else {

            /*
             * Unlike in a singly linked list, we have a direct reference to
             * the last node in the list. Set the `next` pointer of the
             * current last node to `newNode` in order to append the new data
             * to the end of the list. Then, set `newNode.previous` to the current
             * tail to ensure backwards tracking work.
             */
            this[tail].next = newNode;
            newNode.previous = this[tail];
        }

        /*
         * Last, reset `this[tail]` to `newNode` to ensure we are still
         * tracking the last node correctly.
         */
        this[tail] = newNode;
    }
Appends some data to the end of the list.
@param {*} data The data to add to the list.
@returns {void}