The expression expanders[i].this.element means "look up the property on expanders whose name is the value of i, then on the result look up a property called this, and on the result of that, look up a property called element.
But your Expander object doesn't have a property on it called this. If you want to access the Expander object at expanders[i], you just use that, you don't add this. to it:
expanders[i].element.addEventListener("click", function (event) {
// ^--- No this. here
console.log("Clicked " + this);
// Here, use `this` -----^
});
Within the event handler, this will refer to the DOM element that you hooked the event on, so you don't access it via your Expander at all.
If you need to access your expander in there, you need to give yourself a reference to it that will still be valid when the event occurs. You can't use expanders[i] for that with your current loop, because i's value will have changed before the event happens.
You have lots of options for this part, discussed in JavaScript closure inside loops – simple practical example. One of the simplest is to use Array.prototype.forEach instead of for:
Array.prototype.forEach.call(rawElems, function(element, index) {
var expander = expanders[index] = new Expander(element, false);
element.addEventListener("click", function (event) {
// You can use `element` and `expander` here
// If you liked, you could *not* have the `expander` variable
// and use `expanders[index]` here, because unlike the `i` in
// your `for` loop, the value `index` won't change.
});
});
In an ES2015 (aka "ES6") environment or later, you could use let in your for loop: for (let i = 0; i < rawElems.length; ++i) and then expanders[i] would work correctly. (let is quite different from var even though they have similar purposes.)
Or you could use Function.prototype.bind to bind expanders[i] to the event handler function, then use this to refer to the expander, and this.element (or event.currentTarget) to refer to the element. That has the advantage that you can define the handler once and reuse it:
for (var i = 0; i < rawElems.length; i++) {
expanders[i] = new Expander(rawElems[i], false);
expanders[i].element.addaddEventListener("click", handleExpanderClick.bind(expanders[i]));
}
function handleExpanderClick(event) {
// `this` = the expander
// `this.element` = the element
// `event.currentTarget` = the element (also)
}
expanders[i].element.....