Null vs. undefined to represent "None"

I’m trying to build a Double Linked List in javascript. I’m trying to build an _invariant function and in it I’m comparing my this.end value to null.

like so:

DoubeLinkedList.js code
--------------------------------

    _invariant() {

        if(this.begin === null) {
            assert.notEqual(this.end, null, 'this.end has a value while begin does not');
        }

    }

When I read that I think:

   if this.begin is None
        if this.end is not None ... throw an error

I’m curious if I should be using undefined instead? because in my tests the _invarient function fails it’s test. Even though in my test it is set to null.

dll.test.js code
------------------

test('List._invariant() should throw no errors', () => {

    let jobs = new List();
    jobs._invariant();

});

when I run my test suite I get the following response:

dll.test.js output
------------------

  ● List._invariant() should throw no errors

    assert.notEqual(received, expected)     

    Expected value to not be equal to:      
      null
    Received:
      null

    Message:
      this.end has a value while begin does not

    Difference:

    Compared values have no visual difference.

@zberwaldt, I can’t help here – my JavaScript skills are still at an embryonic stage. But I wanted to ask if you would care to share your data structures? I’d be very interested in reading the code.

Of course, I’ve put them in this gist

I’ve included my tests as well. I’m using Jest as my test library.

Any feedback is welcome. Thank you.

1 Like

Thanks! Much appreciated.

Me criticizing JS code… that’d be a bit rich. :slight_smile:

@florian - You’d probably have some good insights, you’d be able to look at things from a different angle than I would.

So, I’ve been reviewing the LMPTHW book. Specifically the Double Linked List chapter. And I think part of my problem is I made and error in my Python implementation in the DLL. In it, I define the _invariant like so:

  def _invariant(self):
        
        if self.count() == 0:
        
            return self.begin == None and self.end == None
        
        elif self.count() == 1:
        
            return self.begin.next == None and self.end.previous == None
        
            return self.begin.next == None and self.begin.previous == None
        
            return self.end.next == None and self.end.previous == None
        
            return self.begin == self.end
        
        elif self.count() > 1:
        
            return self.begin.previous == None
        
            return self.end.next == None
        
        else:
        
            return True, "No errors"
            

And I am calling it directly in my class methods, instead of using it as a testing tool recommended by the chapter.

    def push(self, obj):

       ...

        assert self._invariant()    
       ...

So in the end, my JS code is actually being used correctly, and the test is actually failing for the right reasons. My test for the JS initializes and empty list. I then run the _invariant method. In that function I’m asserting that the List.end is not equal to null. But it IS null, hence the failure. I just need to rewrite it as assert.equal(...).

Just wondering… are those multiple return statements the error you’re referring to?
If not, are you aware that only the first line in each branch of the if statement will ever be evaluated?

Lol. No, I was referring to how I was using it in my class methods. Yes that is a glaring issue (to put it nicely). I can’t believe I’ve been staring at that for a few days and it never registered in my brain. Thank you @florian.

It’s been so long since I’ve coded this I can’t remember how I got to that. A really good reason to comment your code! :laughing: