Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference of methods defined on this in contrast to defined in class body

What is the difference between when I add a method to all instances of a class in the constructor via

this.bar = function() {}

as opposed to defining the function right in the class body

baz() {}

?

class Foo {
  constructor() {
    this.bar = function() {};
  }
  
  baz() {}
}

console.log(Object.prototype.hasOwnProperty.call(new Foo, 'bar')); // true
console.log(Object.prototype.hasOwnProperty.call(new Foo, 'baz')); // false

If I simply replace this.baz with this.baz in the constructor, both tests return true:

class Foo {
  constructor() {
    this.bar = function() {};
    this.baz = this.baz;
  }
  
  baz() {}
}

console.log(Object.prototype.hasOwnProperty.call(new Foo, 'bar')); // true
console.log(Object.prototype.hasOwnProperty.call(new Foo, 'baz')); // true now
like image 200
connexo Avatar asked Aug 21 '20 14:08

connexo


1 Answers

When you do this.bar = function() { }; in the constructor, you're creating a new function for every instance, and assigning it to the bar property. This lets the function close over something in the constructor if you want it to. (And if you used an arrow function, the function would close over this and super.)

When you declare a method in the class, you're creating a single function on the prototype object that class will assign to instances, and reusing that function. This lets the function use super if it needs to access superclass features.

Both have their place depending on what you're doing. You can see that difference here:

class Foo1 {
    constructor() {
        this.bar = function() {};
    }
}

class Foo2 {
    bar() {}
}

const f1a = new Foo1();
const f1b = new Foo1();
console.log(f1a.bar === f1b.bar); // false

const f2a = new Foo2();
const f2b = new Foo2();
console.log(f2a.bar === f2b.bar); // true

About this:

this.baz = this.baz;

in

class Foo {
  constructor() {
    this.bar = function() {};
//             vvvvvvvv−−−−−−−−−−−−−−− reads from the prototype
    this.baz = this.baz;
//  ^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−− writes to the instance

  }
  
  baz() {}
}

that's looking up the function on the prototype, and then assigning it directly on the object, which is why it becomes an own property after that assignment.

like image 78
T.J. Crowder Avatar answered Sep 24 '22 15:09

T.J. Crowder