0

In the MDN Docs, When a static or prototype method is called without a value for this, such as by assigning the method to a variable and then calling it, the this value will be undefined inside the method.


class Animal {
  speak() {
    return this;
  }
  static eat() {
    return this;
  }
}

const obj = new Animal();
obj.speak(); // the Animal object
const speak = obj.speak;
speak(); // undefined

Animal.eat() // class Animal
const eat = Animal.eat;
eat(); // undefined

I dont understand that when we save a normal/static method reference to a variable, why do we lose the reference of this?

Also speak() is like a normal class method. Is this method said to be a prototype method in the text above?

As a solution, it is written:

If we rewrite the above using traditional function-based syntax in non–strict mode, then this method calls are automatically bound to the initial this value, which by default is the global object. In strict mode, autobinding will not happen; the value of this remains as passed.

And the code provided as a solution:


function Animal() { }

Animal.prototype.speak = function () {
  return this;
}

Animal.eat = function () {
  return this;
}

const obj = new Animal();
const speak = obj.speak;
speak(); // global object (in non–strict mode)

const eat = Animal.eat;
eat(); // global object (in non-strict mode)

“ then this method calls are automatically bound to the initial this value, which by default is the global object.” - in which line does the this method call take place?

Link : MDN Docs link

chrslg
  • 9,023
  • 5
  • 17
  • 31
ritwick_ _D
  • 117
  • 1
  • 11
  • "*I dont understand that when we save a normal/static method reference to a variable, why do we lose the reference of this?*" because for ***all*** non-arrow functions\*, the value of `this` is determined at call time. Change the way it is called, and you can affect the value of `this`. \*bound functions are also an exception but probably better to think of "arrow" vs "non-arrow" functions, rather than introducing sub-categories with exceptions which are rare. – VLAZ Nov 11 '22 at 14:15
  • A more technical reason is that `obj.speak()` is a call expression which internally works with a ReferenceRecord. A ReferenceRecord is a _specification type_ which indeed “remembers” the “context” of the call (i.e. the `obj` before `.speak()`) (how exactly this happens is an implementation detail), but this type doesn’t exist in the language as is; if you _assign_ the method elsewhere, then the ReferenceRecord must be evaluated in order to be converted to a _language type_; the resulting language type will be a (function) object, and objects don’t “remember” the “context”. – Sebastian Simon Nov 11 '22 at 14:22
  • So this is simply not how JS works. See [How does the "this" keyword work, and when should it be used?](/q/3127429/4642212). – Sebastian Simon Nov 11 '22 at 14:22

0 Answers0