Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can’t move a method that uses super

I'm reading this book. Check section "15.6.4.2 Pitfall: A method that uses super can’t be moved"

It states the following

You can’t move a method that uses super: Such a method has the internal slot [[HomeObject]] that ties it to the object it was created in. If you move it via an assignment, it will continue to refer to the superproperties of the original object.

So, I tried to call it with a different object, also assign instance method to a different object but it seems not to work. It refers to new object's properties. Probably, I didn't get correctly what the author means. So, could anyone, please, provide an example?

Hers is a small demo and the code below

class A {
  get a() {
    return 1;
  }

  sayHi() {
    console.log(this.a)
  }
}

class B extends A {
  sayHi() {
    super.sayHi();
  };
}
var obj = {
  a: 4
};
let b = new B();
b.sayHi();
// logs 1

b.sayHi.call(obj);
// logs 4

obj.sayHi = b.sayHi;
obj.sayHi();
// logs 4
like image 954
Olena Horal Avatar asked Jan 28 '23 08:01

Olena Horal


1 Answers

Your code is OK, because this works when you move a method, but super doesn’t (and your code only really tests this). The following code tests super:

class Bird {
  getName() {
    return 'Bird';
  }
}
class Mammal {
  getName() {
    return 'Mammal';
  }
}
class Human extends Mammal {
  getName() {
    return super.getName();
  }
}
class Duck extends Bird {
}
// Moving method .getName() from Human.prototype to Duck.prototype
Duck.prototype.getName = Human.prototype.getName;

console.log(new Duck().getName()); // 'Mammal' (not 'Bird')

To understand the result, you need to understand how super works – it uses the internal property [[HomeObject]] that is stored in the method itself, it does not rely on this. That is, Human.prototype.getName() internally works as follows:

Human.prototype.getName = Object.assign(
  function me() {
    return me.__HomeObject__.__proto__.getName();
  },
  { __HomeObject__: Human.prototype }
);

More details are explained in the book:

like image 100
Axel Rauschmayer Avatar answered Jan 29 '23 22:01

Axel Rauschmayer