JS how to know if child class overrides parent method - javascript

Let's say I have a superclass and a child that overrides one of the super methods.
class Test {
doSomething() {
callsomething({
callback: this.method
})
}
method() {
console.log('parent');
}
}
class A extends Test {
constructor() {
super();
}
method() {
console.log('override');
}
}
new A().method();
There is a way to know inside the Test class if method was overridden?

Inside doSomething, check if this.method refers to Test.prototype.method - if it doesn't, then this.method refers to something else, which means it's been shadowed, quite possibly by a child class method:
class Test {
doSomething() {
if (this.method === Test.prototype.method) {
console.log("Method is native Test's!");
} else {
console.log("Method is not Test's, it's been shadowed!");
}
}
method() {
console.log('parent');
}
}
class A extends Test {
constructor() {
super();
}
method() {
console.log('override');
}
}
new A().doSomething();
new Test().doSomething();
You can also do the same check in Test's constructor:
class Test {
constructor() {
if (this.method === Test.prototype.method) {
console.log("Method is native Test's!");
} else {
console.log("Method is not Test's, it's been shadowed!");
}
}
method() {
console.log('parent');
}
}
class A extends Test {
constructor() {
super();
}
method() {
console.log('override');
}
}
new A()

Related

Javascript how to call overrided method from constructor

I have two classes in javascript a, b. Class b extends a. Class a calls method in constructor. I wanna override this method in b class. How to call overridable method? when I added to class a, to constructor this.method(), it always calls method from a class.
class a {
constructor() {
this.method();
}
method() {
alert("a");
}
}
class b extends a {
constructor() {
super();
}
method() {
alert("b");
}
}
If you don't know in advance whether the instance is of the subclass or superclass, you can make sure the superclass calls its own method by having the superclass reference itself explicitly:
A.prototype.method.call(this);
class A {
constructor() {
A.prototype.method.call(this);
}
method() {
console.log("a");
}
}
class B extends A {
constructor() {
super();
}
method() {
console.log("b");
}
}
const b = new B();
class A {
constructor(){
this.method()
}
method(){
alert("a");
}
}
class B extends A {
constructor(){
super()
}
method(){
alert("b");
}
}
new B();

JavaScript: Method That's Never Loses Binding

Consider this basic custom element:
class XElement extends HTMLElement {
constructor() { super(); }
foo() { console.log( this ); }
} customElements.define( 'x-element', XElement );
Here is the problem:
const xelem = new XElement();
/* `foo` will lose its binding to `xelem`:
*/ someButton.onclick = xelem.foo;
// These will work, but it's too verbose:
someButton.onclick = () => xelem.foo();
someButton.onclick = xelem.foo.bind( xelem );
I see only one solution is to add foo as arrow function in constructor, but it seems to me wrong.
constructor() {
super();
this.foo = () => console.log( this );
}
Is there any right way to create method that will never lose its binding?
That is how JavaScript this binding works.
You can read this: THIS (YDKJS)
Basically, the value of this inside a function depends upon how that function is invoked. So you need to explicitly hard bind the this value to your function foo by using the bind() method or defining foo as arrow function (arrow functions lexically bind their context).
So the solution is what you found.
You can do:
In your constructor:
class XElement extends HTMLElement {
constructor() {
super();
this.foo = this.foo.bind(this);
}
foo() { console.log( this ); }
}
Or (I don't like this one)
class XElement extends HTMLElement {
constructor() {
super();
this.foo = () => console.log(this);
}
}
Or
class XElement extends HTMLElement {
constructor() { super(); }
foo = () => { console.log( this ); }
}

Shared logic between constructor and another function in Java Script

I have a situation like that:
class TestClass {
constructor() {
shared logic
}
anotherFunction() {
shared logic
}
}
How can I achieve that not duplicating the code?
As always, create a function for the shared logic, either inside of the class or outside of it.
class TestClass {
constructor() {
this.sharedLogicFunction();
}
anotherFunction() {
this.sharedLogicFunction();
}
sharedLogicFunction() {}
}
Put your code to the anotherFunction() and call this function from constructor.
class TestClass {
constructor() {
this.anotherFunction();
}
anotherFunction() {
here is some logic to do
}
}

Save extending class' methods' names in constructor

I have three classes, two of them extending the third. Is it possible to somehow (different than manually) assign extending classes' names to the super constructor?
class Master {
constructor(options) {
this.methods = Object.getOwnPropertyNames( Master.prototype );
}
getMethods() {
return Object.getOwnPropertyNames( Master.prototype );
}
}
class SlaveOne extends Master {
constructor(options) {
super(options);
}
methodOne() {}
methodTwo() {}
}
class SlaveTwo extends Master {
constructor(options) {
super(options);
}
methodThree() {}
methodFour() {}
}
So, what I want is to have either method or this.methods assignment in the Master class, which will:
return ['constructor', 'methodOne', 'methodTwo'] when called on an instance of SlaveOne;
return ['constructor', 'methodThree', 'methodFour'] when called on an instance of SlaveTwo;
My current code will return same ['constructor', 'getMethods'] when called either on instance of SlaveOne, SlaveTwo or Master. Any ideas?
Something like this should do the trick
class Master {
getMethods() {
return Object.getOwnPropertyNames( this.constructor.prototype );
}
}
class SlaveOne extends Master {
constructor(options) {
super(options);
}
methodOne() {}
methodTwo() {}
}
class SlaveTwo extends Master {
constructor(options) {
super(options);
}
methodThree() {}
methodFour() {}
}
console.log(new SlaveOne().getMethods(), new SlaveTwo().getMethods())

call function at extends constructor

class PathController {
constructor(){
}
getMainPage(){
alert("getMainPage");
}
setPushState(){
alert("setPushState");
}
}
class MainMenu extends PathController {
constructor (){
// call my PathController here
super();
getMainPage();
setPushState();
}
}
let aMainMenu = new MainMenu();
my intention is to call my getMainPage and setPushState at my MainMenu constructor , i tired this.getMainPage and this.setPushState and it is not working as well. can anyone tell me how to call it ?
Your super is your "this" since we are currently in the constructor. Here's how it should look:
class PathController {
constructor(){
}
getMainPage(){
alert("getMainPage");
}
setPushState(){
alert("setPushState");
}
}
class MainMenu extends PathController {
constructor (){
// call my PathController here
super();
super.getMainPage();
super.setPushState();
}
}
let aMainMenu = new MainMenu();
However once you are outside of the constructor, then you would use "this.getMainPage();"
One approach would be to pass property names to super() which call the functions at PathController parent constructor
class PathController {
constructor(fromMainMenu, ...props) {
if (fromMainMenu) {
for (let fn of props) {
this[fn]()
}
}
}
getMainPage(){
alert("getMainPage");
}
setPushState(){
alert("setPushState");
}
}
class MainMenu extends PathController {
constructor () {
// call my PathController here
super(true, "getMainPage", "setPushState");
}
}
let aMainMenu = new MainMenu();

Categories

Resources