-2

I have this class

class Dark {
    constructor(name) {
        this.name = name;
    }
    destroy() {
       console.log("method called")
        console.log(this);
    }
}

const DarkObject = new Dark('DarkObject');

const copyDarkObject = {destroy: DarkObject.destroy}

console.log(copyDarkObject.destroy())

//> method called
// > undefined

I stored the reference of the class method to the key of a other Object

const copyDarkObject = { destroy: DarkObject.destroy };

the created Object is not the owner of the method so the return is undefined thats clear to me but I can still invoke the method from the key with console.log(copyDarkObject.destroy())
how is that possible ?

seeman
  • 105
  • 1
  • 13
  • 1
    You still have a function reference and that can still be executed. Why wouldn't that be possible? – VLAZ Jan 31 '21 at 08:42
  • I can not get that its possible to "invoke" the key `copyDarkObject.destroy()` – seeman Jan 31 '21 at 08:45
  • But *why*? You seem to understand [function references](https://stackoverflow.com/q/15886272) already because [you weren't surprised by the behaviour of `this`](https://stackoverflow.com/q/20279484). I'm not sure why you expect a function reference to not be callable. – VLAZ Jan 31 '21 at 08:49

2 Answers2

2

the created Object is not the owner of the method so the return is undefined

No. The statement

console.log(copyDarkObject.destroy())

logs undefined because the destroy method doesn't return anything (since it doesn't use a return statement).

The statement

console.log(this)

in the destroy method will log your copyDarkObject, because destroy was called on copyDarkObject.

And that's why the log says:

method called
Object { destroy: destroy() }       // the object destroy was invoked on
undefined                           // the return value of destoy
meriton
  • 68,356
  • 14
  • 108
  • 175
0

Class keyword in JavaScript is just syntactic sugar.
Under the hood it is still prototype based inheritance/system, which allows some extra flexibility.

What exactly happens in your code:

  1. You see returned value undefined - this is correct, because you never return anything from destroy() and Js by default "returns" undefined from functions.
  2. You create a new object giving it one property, which is a reference to darkObject.destroy - value of this pointer/reference in Js depends on how function was called.
    You can read up on MDN on how built-in function like bind() or apply or call work.
    In this case when you call destroy on copyOfDarkObject, this points to copyOfDarkObject

class Dark {
    constructor(name) {
        this.name = name;
    }
    destroy() {
       console.log('I am calling destroy on', this);
       return `I am ${this.name}`;
    }
}

const darkObject = new Dark('DarkObject');
const copyOfDarkObject = {destroy: darkObject.destroy}

console.log('returned value', copyOfDarkObject.destroy());
console.log('returned value', darkObject.destroy());

console.log(copyOfDarkObject instanceof Dark);
console.log(darkObject instanceof Dark);

Some extra info:

While logging this you can see, that copyOfDarkObject has one property called destroy, but darkObject only one called name. It is so, because destroy method exists on darkObject prototype and you don't see it directly on the object.

matvs
  • 1,763
  • 16
  • 26