2

class Boy {
  sayName = function() {
    console.log('You should rewrite this method!')
  }
  sayName2 = function() {
    return
  }
}

class BabyBoy extends Boy {
  sayName() {
    console.log('I have rewritten this method!')
  }
}

var babyBoy = new BabyBoy()

babyBoy.sayName() // here it outputs: You should rewrite this method!

How did it happen?? It's been bugging me for hours! It seems that there exists some difference between method() and method = function(){}.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
kqhasaki
  • 31
  • 2
  • Are you this question? https://stackoverflow.com/questions/15285293/method-vs-functions-and-other-questions – Rayees AC Jul 28 '20 at 17:53
  • Check out the difference between `BabyBoy.prototype` and `Boy.prototype`. – Brad Jul 28 '20 at 17:54
  • 3
    `method(){}` goes to prototype. `method = function(){}` goes to every instance as a property. Member resolution order in javascript first checks if instance has the property, only then goes up the prototype chain. That is why you get property created in parent constructor. – Yury Tarabanko Jul 28 '20 at 17:58
  • sayName inherited from Boy is treated as a property so when js tries to execute sayName, it will first check the instance properties. if not found it searches in the instance prototype – AngelSalazar Jul 28 '20 at 17:58

1 Answers1

1

Let's "desugar" your code a bit by creating explicit constructor functions (which classes basically are under the hood) and moving public class field definition to the constructor

class Boy {
  constructor() {
    // move public fields to constructor
    this.sayName = function() {
      console.log('You should rewrite this method!')
    }
  }
  
  // define prototype method
  prototypeMethod() {}
}

class BabyBoy extends Boy {
  // add explicit construtor
  constructor() {
    // that calls super
    super()
  }

  sayName() {
    console.log('I have rewritten this method!')
  }

  // override prototype method
  prototypeMethod() {}

}

var babyBoy = new BabyBoy()
var anotherBabyBoy = new BabyBoy()

// lets first ensure that every instance has its own properties
console.log(`babyBoy.sayName === anotherBabyBoy.sayName is ${babyBoy.sayName === anotherBabyBoy.sayName}`)

// check that it doesn't come from prototype
console.log(`babyBoy.sayName === BabyBoy.prototype.sayName is ${babyBoy.sayName === BabyBoy.prototype.sayName}`)

// then make ensure that every instance shares the same method from prototype
console.log(`babyBoy.prototypeMethod === anotherBabyBoy.prototypeMethod is ${babyBoy.prototypeMethod === anotherBabyBoy.prototypeMethod}`)

// check that it comes from prototype
console.log(`babyBoy.prototypeMethod === BabyBoy.prototype.prototypeMethod is ${babyBoy.prototypeMethod === BabyBoy.prototype.prototypeMethod}`)
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98