Here is my parent.class.js
class ParentClass {
constructor() {
}
}
module.exports = { ParentClass };
child.class.js
const { ParentClass } = require('./parent.class');
class ChildClass extends ParentClass {
constructor(index) {
super();
this.index = index;
}
showIndex() {
console.log(this.index)
}
}
module.exports = { ChildClass };
And index.js where I'm using the child class
const ChildClass = require('./child.class');
ChildClass(1).showIndex(); // This obviously is not working
NOTE: this is only an example. In the actual project I'm not able to use ES6 module import
My question is how can I pass parameters to child class instance in my index.js?
In case of ES6 I would be able to do something like this:
import ChildClass from './child.class.js'
const ChildClass = new ChildClass(1)
ChildClass.showIndex(); // outputs 1 ...I guess??
How do I pass argument to the childclass?
The problem is
module.exports = { ChildClass };
and
const ChildClass = require('./child.class');
You're exporting an object which has a property of ChildClass there, and then you're importing the whole object and trying to call it. But objects aren't callable; you aren't referring to the ChildClass class.
Just like you destructured the ParentClass with
const { ParentClass } = require('./parent.class');
Either destructure the ChildClass:
const { ChildClass } = require('./child.class');
Or assign the ChildClass to the module.exports:
module.exports = ChildClass;
And then you'll be able to create instances of the ChildClass and call methods on the instance:
const child = new ChildClass(1);
child.showIndex();
Related
i am having some issues learning class methods syntaxes... there are a few and I dont know if they have different behaviours or if they are just equivalent/updated versions of one another.
is my thoughts real?
class Person {
constructor(name) {
this.name = name
}
instanceMethod() { // this.
console.log('hello there')
}
}
Person.prototype.instanceMethod = () => { //equivalent to this?
}
const person = new Person()
person.instanceMethod // so we call the "person.prototype.instanceMethod'' in the instance of the class
// ... //
class Person {
constructor(name) {
this.name = name
}
static staticMethod() { // this.
console.log('hello there')
}
}
class OtherPerson extends Person {
}
Person.staticMethod = () => { // is equivalent to this?
}
const person = new Person()
Person.staticMethod() // so we call the static method in the Parent Class
OtherPerson.staticMethod //or a child class of that Parent Class.
or to call in the child class of the class you have to provide their own static methods?
class OtherPerson extends Person {
(... constructor and stuff...)
staticMethod() { console.log('hello there') } // defining their own static methods.
staticMethod() { super.staticMethod() } //or make this as well... both with same results
}
In a library that I wish to extend without modifying its code, several classes inherit from the same imported one. That is in this BaseClass I would need to overwrite a specific method.
In the library (written in TypeScript) :
import { BaseClass } from './base_class';
export class ClassA extends BaseClass {}
import { BaseClass } from './base_class';
export class ClassB extends BaseClass {}
…
In the external extension I wish to write :
import { BaseClass } from 'library';
export class ExtendedBaseClass extends BaseClass {
oneMethod() {
const data = BaseClass.prototype.oneMethod.call(this);
// make additional things with data
return data;
}
}
Is there a way for this new ExtendedBaseClass to become the parent of all ClassXs ? At least in a new extended and re-exported version of them without the need to copy their internal code.
Is there a way for this new ExtendedBaseClass to become the parent of all ClassXs?
No.
An alternative might be to replace the one method directly on the base class:
import { BaseClass } from 'library';
const oneMethod = BaseClass.prototype.oneMethod;
Object.defineProperty(BaseClass.prototype, 'oneMethod', {
value() {
const data = oneMethod.call(this);
// make additional things with data
return data;
},
});
There's no way to do exactly what you're asking, but you could achieve the same result by extending each class individually.
ExtendedClassA extends ClassA {
oneMethod() {
// call a shared method if you need to reuse
}
}
// ExtendedClassB, etc
I have declared a class, like:
export default class Utils {
static deepClone(): object {
return {}
}
}
so when I want to use deepClone, I can:
// First One
import Utils from './Utils';
export default class Element {
constructor(){
this.utils = new Utils()
}
create(){
return this.utils.deepClone()
}
}
or:
// Second One
import Utils from './Utils';
export default class Element {
constructor(){
this.utils = Utils
// this is an optional
// in my child class I need't to import Utils
// I can use this.utils.deepClone() directly
}
create(){
return Utils.deepClone()
}
}
I wonder which is a better way to imply Element class
Looking forward to your reply, I can’t thank you enough
The second way is more correct but it has a problem that you should create an instance of Utils class to use each property which isn't a static method.
The output of a class that you didn't create an instance is a function instead of an object of prototypes.
./Utils.js
export default class Utils {
static deepClone(): object {
return {}
}
public deepExtend() {
// deepClone code
}
}
Use in another file:
import Utils from './Utils';
export default class Element {
constructor(){
this.utils = new Utils();
}
create(){
return Utils.deepClone()
}
extend(){
return this.utils.deepExtend()
}
}
I would return export new of the Utils and I will pass it in the constructor of your Element as an Instance, something like:
IUtils = someInterface;
export default class Element {
constructor(utils: IUtils){
this.utils = utils;
}
create(){
return this.utils.deepClone()
}
}
In these way it:
Doesn't create new instances for nothing
Uses other instances that you can pass to your Element class
Is testable
Using ES6 is there a way to apply multiple mixins which are defined in an array? The mixins would be defined as such:
const mixins = Array('Mixin', 'Mixin2');
Then creating a mixin with:
export const Mixin = function (superClass) {
return class extends superClass {}
And using the mixin with:
export class MyClass extends MultipleMixins(BaseClass)
You can use reduce() over the array of mixins, pass in a base class and keep returning a new mixed class. This will just apply all the mixing in order:
class BaseClass {
constructor(name) {
this.name = name
}
}
// adds an uppercase
const Mixin = function(superClass) {
return class extends superClass {
get uppercase() {
this.name = this.name.toUpperCase()
return this
}
}
}
//adds a reverse
const Mixin2 = function(superClass) {
return class extends superClass {
get reverse() {
this.name = [...this.name].reverse().join('')
return this
}
}
}
let mixins = [Mixin, Mixin2]
let MixedClass = mixins.reduce((base, mix) => mix(base), BaseClass)
let instance = new MixedClass('mark')
// use the new methods
console.log("reversed & uppercase:", instance.uppercase.reverse.name)
This is my main class (it uses a subclass:)
import SubClass from './SubClass'
class MainClass extends classes(SubClass) {
constructor () {
// some code
}
}
window.MainClass = new MainClass()
export default MainClass
This is the subclass:
class SubClass {
constructor () {
this.someMethod = function () {
// some code
}
}
}
export default SubClass
If I want to use a method from the SubClass I can write: MainClass.someMethod.
How to modify this code so I write: MainClass.SubClass.someMethod instead?
So I can write:
MainClass.SubClass.someMethod
MainClass.SubClass2.someMethod
In case I need another SubClass?
I think you need to call super(). And classes() seem doen't need to be added.
When used in a constructor, the super keyword appears alone and must be used before the this keyword is used.
See document
import SubClass from './SubClass'
class MainClass extends SubClass {
constructor () {
super();
console.log(this.someMethod)
}
}
Hope this help