Heyy there, I think you have a missunderstanding right up that question! Inheritance and Composition are basic principles which can apply to OOP :)
Inheritance means, that you have an object, which is derived from another object. Composition means, that you have two or more objects which you mix in order to create a new object. Basically, Composition is the generic form of Inheritance.
Personally, I think we need both, but if both are applicable, prefer Composition.
As for the question "is OOP bad?": No! By all means, OOP is just one way of code architecture. It is not bad per-se. It's more along the lines "use the right tool for the right job." Think of it as: You go on a picknick. Then it starts to rain. Because of that, you will probably say that rain is bad, but on the other side, plants need that rain and for them it is good!
Well, all in all, I like to mix things and use them whenever appropriate, so you will find some FP and OOP in my projects, mixed and happily living next to each other, based on what I need at that certain point :)
Examples of Inheritance and Composition in OOP (JS):
// Inheritance
class Parent {
foo() {};
};
class Child extends Parent {
bar() {};
};
const obj = new Child();
obj.foo(); // ok
obj instanceof Parent; // true
// Composition (simple & stupid)
const Base = {
foo: () => {},
};
const Mixin = {
bar: () => {},
};
const obj = Object.assign({}, Base, Mixin);
obj.foo(); // ok
obj instanceof Base; // false (!!!)
// Composition (correct)
const mx = require('mixwith');
const Base = class {
foo() {};
};
const Mixin = mx.Mixin(superclass => class extends superclass {
bar() {};
});
class MixedClass extends mx.mix(Base).with(Mixin) {};
const obj = new MixedClass();
obj.bar(); // ok
obj instanceof Base; // true