I have a class B which implements another class A.
In the class A I need to use variables defined in class B
class classA {
methodA() {
console.log(parentClass.variableToRetrieve);
}
}
class classB {
constructor() {
this.variableToRetrieve = 1;
this.A = new classA();
}
}
var B = new classB();
B.A.methodA();
Whats should I use in classA.methodA ans see 1 in the console ?
Edit
I already thougth to pass the B object in the classA constructor, or pass values, but as I can have hundreds variables and (potentially) millions classA, it will fuck the server quickly
You should extend classB with classA
class classA {
methodA() {
console.log('parentClass.variableToRetrieve');
}
}
class classB extends classA {
constructor() {
super()
this.variableToRetrieve = 1;
}
method() {
this.A = new classA();
}
}
var B = new classB();
B.methodA();
Updated:
I think binding the classB will solve will problem.
class classA {
methodA() {
console.log(this.variableToRetrieve);
}
}
class classB {
constructor() {
this.variableToRetrieve = 4;
}
}
var B = new classB();
var A = new classA();
A.methodA.bind(B)();
Your class A must extend class class B to do that
Related
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.
I want to create an inheritance where I have class defined and creating inheritance using function
class ClassA{
constructor(){
this.name = "Kanike"
}
}
function ClassB(jkk){
new ClassA()
this.last = jkk
}
ClassB.prototype = ClassA.prototype
var myClassB = new ClassB("kel");
alert(myClassB.name)//cant be accessed here
This is what the extends keyword is for. Extend the class and you can access both the name and last fields:
class ClassA {
constructor() {
this.name = "Kanike";
}
}
class ClassB extends ClassA {
constructor(last) {
super();
this.last = last;
}
}
let classB = new ClassB("Kel");
console.log(classB.name, classB.last);
I am sorry if the heading is misleading, I can't think of a better heading.
so I have two classes like this :
class ClassA{
getObject(){
return new this(with some parameters)
}
}
class ClassB extends classA{
}
let a = new ClassB();
a.getObject();
I know I can always return new ClassB() with some parameters. But ClassA is extended by some hundred classes and it will be a lot of change in every class.
So Is there a way to return object of self class in getObject method of ClassA?
You can use polymorphic this to return an instance of the same type as the current class:
class ClassA {
getObject(): this {
// not really type safe, not really recomnded
return new (this as any).constructor()
}
}
class ClassB extends ClassA {
}
let a = new ClassB();
let b = a.getObject(); // ClassB
console.log(a.getObject() instanceof ClassB); // true
You can also infer the type of this using a type parameter and use that as the return type:
class ClassA {
getObject<T>(this:T) : T {
// not really type safe
return new (this as any).constructor()
}
}
class ClassB extends ClassA {
}
let a = new ClassB();
let b = a.getObject(); // ClassB
console.log(a.getObject() instanceof ClassB); // true
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
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.