import a method from a class into another class JS - javascript

I'm still beginner in JS and I feel like I'm often dealing with some basic stuffs out here.. I want to retrieve/import a method from a class A into class B (using modules). Also, I don't know if my code is well built so I'm open for all suggestions and advices.
Here's class 1 (A)
export default class A {
constructor() {
this.zone = document.getElementById('#zone');
this.array = [];
this.init();
}
init() {
//code
}
methodToImport(id) {
let DOM = `<h1>HTML Content</h1>`
this.zone.insertAdjacentHTML('beforeend', DOM);
this.array.push(new B(this.zone.lastElementChild));
}
and here's class 2 (B)
import A from "./A.js";
class B {
constructor(element) {
this.init();
}
init() {
// here I want to retrieve the array duly wholy fillen with instances of class A
console.log(A.array);
}
}
I really wish you could help, thank you guys !

you can create an object of class A in class B and use it.
class A {
constructor() {
this.zone = document.getElementById('#zone');
this.array = [1,2,3,4];
}
}
class B {
constructor(element) {
this.a = new A;
}
}
b = new B
console.log(b.a.array);

Related

Multiple classes that have a different name but extends the same class

I have for example this class:
abstract class MyClass {
abstract myProp: number;
constructor() {
// Some code
}
}
So I want to create multiple classes that extends this class. But I don't want to repeat it multiple times as I will have a lot of classes. So the purpose is that each class has a different name and myProp.
For example:
class FirstClass extends MyClass {
myProp = 1;
constructor() {
super();
// Some code
}
}
class SecondClass extends MyClass {
myProp = 2;
constructor() {
super();
// Some code
}
}
So I want to generate these classes (with for example a function) but the problem is that I will have to use the new keyword.
So the usage for each of these classes should be like this:
const myConst = new FirstClass();
const myConst2 = new SecondClass();
I hope this makes some sense. I just don't want to repeat every class because it has a different name and myProp.
You can create classes through a function that returns an anonymous class.
const createClass = ( prop: number ) => {
return class extends MyClass {
myProp: number;
constructor () {
super();
this.myProp = prop;
}
}
}
const FirstClass = createClass(1);
const x = new FirstClass();
console.log(x.myProp);
Or check out the answers to these questions for ideas:
ES6 Dynamic class names
Create object from class name in JavasScript ECMAScript 6
If I understand your problem correctly, you could just pass the variable that's different as an argument in the constructor.
class MyClass {
myProp: number;
constructor(myProp: number) {
this.myProp = myProp
// Some code
}
}
And then create the class instances you want.
const myConst = new MyClass(1);
const myConst2 = new MyClass(2);
Personally, I would only extend a class if I want to add some methods or properties that aren't shared. Since myProp exists in both classes, it's probably better to just pass the value to the constructor.

What is proper way of inheritance is JS with initialization method

I have such code. And it works like I expect.
class colorObj {
constructor() {
this.color = new Color();
}
init() {
this.color.setColor(
calcColor() // Could be long
);
}
}
class sizeObj extends colorObj {
constructor() {
super();
this.size = new Size();
}
init() {
super.init();
this.size.setSize('10x10');
}
}
let obj = new sizeObj();
obj.init(); // (1)
obj.color.setColor('green');
obj.init();
But now I want to remove first init() call (1). And I can't understand how can I call it inside class hierarchy. I can't call this.init() in colorObj, because new Size(); have not been done yet.
Main idea is to split object allocation in constructor from it's initialization in init() method.
Also I want to have opportunity to "reset" object in any place with init() call. Without new object allocation.
I can make it with such code:
class sizeObj extends colorObj {
constructor() {
super();
this.size = new Size();
sizeObj.prototype.init.call(this, false);
}
init(initializeSuper = true) {
if ( initializeSuper ) {
super.init();
}
this.size.setSize('10x10');
}
}
It works. But I hope to find less awful solution.
Also I can do that:
class sizeObj extends colorObj {
constructor() {
super();
this.size = new Size();
this.initSizeObj();
}
init() {
super.init();
this.initSizeObj();
}
initSizeObj() {
this.size.setSize('10x10');
}
}
But it is also looks for me like tangled solution.
Thank you :)

Use all functions of another object in javascript

I couldn't find the solution to this issue. I am banging my head against a wall entire day.
Assume we have the following hierarchy of classes:
class A {
async name() { ... }
}
class B extends A {
async age() { ... }
}
class C extends A {
async group() { ... }
}
class D extends B {
constructor() {
super(...)
this.C = new C(...);
}
async group() { return await this.C.group(); }
}
Because JavaScript doesn't support multiple inheritance, I have an issue. I would like to combine prototypes of objects in a way that I can invoke function group() without the need for writing repetitive code like above. It is absolute must to be able to invoke group() directly on the object D outside of the class, even though it is the an instance of class C.
How can I combine their prototypes? I've tried things like
class A {
appendPrototype(obj) {
if (obj instanceof A)
for (let k in obj.__proto__) {
this.__proto__[k] = obj.__proto__[k];
}
}
}
.
.
. // Same two classes, B and C
class D extends B {
constructor(...) {
super(...);
const c = new C(...);
this.appendPrototype(c);
}
}
I can't invoke the function group() an instance of the class D. Why is that? How can I achieve it, without writing repetitive code like in the first example?
What you can do, it is to assign to the prototype of the class D, the method of the class C.
In this way all the instances of D will have the group method which is the same method defined within the class C, and you can do the same for all the other child classes.
class A {
async name() {
console.log('A - name');
}
}
class B extends A {
async age() {
console.log('B - age');
}
}
class C extends A {
async group() {
console.log('C - group');
}
}
class D extends B {
constructor() {
super();
}
}
D.prototype.group = C.prototype.group;
const d = new D();
d.group();
Anyway, in your case, I would go for composition (like you did with C within D) and then call the methods like:
d.c.group()
which allows you to avoid the appendPrototype logic.

Promoting object in JavaScript

So I have a class and another class that extends the first one.
I would like to know if it's possible to promote the extended class from the first one in JavaScript.
class Class1 {
constructor(data) {
this.var1 = data.var1
this.var2 = data.var2
}
}
class Class2 extends Class1 {
constructor(o) {
this = o
this.var3 = '!!!'
}
}
const o = new Class1({var1: 'HELLO', var2: 'WORLD'})
const o2 = new Class2(o)
console.log(o2.var1)
console.log(o2.var2)
I know that this = o is going to throw an error. But is there a way to accomplish the task without having to assign every field from the old object to a new one?
You can use the super() function:
class Class1 {
constructor(data) {
this.var1 = data.var1
this.var2 = data.var2
}
}
class Class2 extends Class1 {
constructor(o) {
super(o)
this.var3 = '!!!'
}
}
const o = new Class1({var1: 'HELLO', var2: 'WORLD'})
const o2 = new Class2(o)
console.log(o2.var1) // -> HELLO
console.log(o2.var2) // -> WORLD
More info on super(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
You can call super(o) at the beginning of the constructor on class2
Demo fiddle

How do I call a super constructor outside a constructor?

Now that JavaScript has classes I'm wondering how it is possible to invoke a super constructor outside of a class constructor.
My unsuccessful naive attempt (results in a SyntaxError):
class A
{
constructor() { this.a = 1; }
}
function initB()
{
super(); // How to invoke new A() on this here?
this.b = 2;
}
class B extends A
{
constructor() { initB.call(this); }
}
I'm aware that in some other language like Java a super constructor can only be invoked inside the constructor of a derived class, but ES6 classes are syntactic sugar for prototype-based inheritance, so I'd be surprised if this were not feasible using built-in language features. I just can't seem to figure out the proper syntax.
The best I've come with so far feels terribly like cheating:
class A
{
constructor() { this.a = 1; }
}
function initB()
{
let newThis = new A();
newThis.b = 2;
return newThis;
}
class B extends A
{
constructor() { return initB(); }
}
Every constructor of a class that extends something must contain a direct super(…) call.
Direct super(…) calls can only be placed in constructors. There's really no way around this.
You really should not place the initialisation logic of a class anywhere else than in its constructor. The straightforward and proper solution is not to use initB at all:
class A {
constructor() { this.a = 1; }
}
class B extends A {
constructor() {
super();
this.b = 2;
}
}
That said, there is a way to subvert the "super() call must be in the constructor" requirement. Putting it inside an arrow function counts as well! So you could do
class A {
constructor() { this.a = 1; }
}
function initB(_super) {
var b = _super();
b.b = 2;
}
class B extends A {
constructor() {
initB(() => super());
}
}
Promise me to not ever do that, please.
Another pattern is not to call super() at all, which works as long as you return an object from the constructor. With that, you can put the actual construction of the object anywhere else:
class A {
constructor() { this.a = 1; }
}
function makeB() {
var b = Reflect.construct(A, [], B); // call the A constructor with B for the prototype
b.b = 2;
return b;
}
class B extends A {
constructor() {
return makeB();
}
}
Which really isn't much better.

Categories

Resources