Search code examples
javascriptarraysobjectconstructorpush

Push to array from constructor in plain JavaScript


I'm trying to build an array of objects from within the constructor. I don't know if it's even possible or advisable. But I'm trying to build this for practice, and I wonder why it isn't working.

// Variables.
const VVD = new Party("VVD", 33);

// List of objects.
var theList = [];

// Party constructor.
function Party(name, seats) {
	this.name = name;
	this.seats = seats;
	//theList.push(this); // This isn't working.
	this.pushToTheList = function() { 
		theList.push(this);
	}
	this.pushToTheList(); // And neither is this.
}

This is the error I'm getting: Uncaught TypeError: Cannot read property 'push' of undefined Even if I replace this with "test", I'm still getting the same error.

While outside of the constructor, this is working fine: theList.push(VVD);

Why isn't this working? And is there a better, smarter way to push objects to arrays?

A link to CodePen: http://codepen.io/MichaelVanDenBerg/pen/gmXZej


Solution

  • Your Party constructor is being called before you create your theList array.

    Function declarations (like your Party constructor) are hoisted to the top of their scope; however, assignments to variables like theList = [] are not (even though the var theList declaration itself is hoisted). Thus, your code is being interpreted like this:

    var theList;
    
    // Variables.
    const VVD = new Party("VVD", 33);
    
    // List of objects.
    theList = [];
    

    You can see more clearly here why theList is undefined when your constructor is first called. Try reordering the statements so that theList is created before VVD:

    // List of objects.
    var theList = [];
    
    // Variables.
    const VVD = new Party("VVD", 33);
    
    
    // Party constructor.
    function Party(name, seats) {
    	this.name = name;
    	this.seats = seats;
    	//theList.push(this); // This works
    	this.pushToTheList = function() { 
    		theList.push(this);
    	}
    	this.pushToTheList(); // And so does this.
    }
    
    console.log(theList)