mozjs was a pretty old codebase with some design decisions that made sense in the mid-90s but don't make sense now baked into the API.
The API needed to change to support things like a generational garbage collector. The set of needed API changes was quite large.
Now the project had two options: Make the changes incrementally or all at once. The incremental option would mean API changes with each release until all the changes got made. The all at once option would mean you'd need to do a complete rewrite of all the relevant mozjs code and all the relevant Firefox code all landing in a single release. Since the time needed for that rewrite was measured in years, that would mean maintaining a branch and dealing with all the merge conflicts from other ongoing work. In practice, it would have meant a much slower pace of web-facing JS feature development at best; more likely a complete stop to that.
Given those choices, the JS team went for the incremental route. Yes, it was painful for API consumers who needed to be running against current versions. But in this case, I expect it was the right tradeoff.
I should also note that V8 breaks API compat regularly, though not to the extent that SpiderMonkey had to, due to being designed 15 years later with many benefits of hindsight.
[Disclosure: I work on Firefox, closely with the JS team but not on the JS team.]