0

I have this piece of code:

class MyClass {
  constructor(text, pattern) {
    this.text = text;
    this.pattern = pattern;
  }

  run() {
    return this.text.replace(/(\d)/, this.replacer)
  }

  replacer(match, timeString, offset, string) {
    return this.pattern;
  }
}

It is a simplified example of my actual code.

When I run:

var v = new MyClass("text 1 2", "X");
v.run();

I see the error:

Uncaught TypeError: Cannot read properties of undefined (reading 'pattern')

How can access to this in this replacer function?

fguillen
  • 36,125
  • 23
  • 149
  • 210
  • replace `this.replacer` with `this.replacer.bind(this)` – Mulan Dec 13 '21 at 19:22
  • The `this.replacer` callback in the `.replace()` function is just a reference to the function at the prototype of `MyClass`. However when it gets invoked as a callback from within `.replace()`, the `this` in it, namely the one at `this.pattern` represents the `String` object, which doesn't have a `pattern` property so `this.pattern` becomes `undefined`. So yes, you should `.bind()` it to `this` inside the constructor while the `this` still represents the instance to be. – Redu Dec 13 '21 at 19:55

1 Answers1

3

Use Function#bind to set the this value, or use an arrow function that calls this.replacer as the callback.

class MyClass {
  constructor(text, pattern) {
    this.text = text;
    this.pattern = pattern;
  }

  run() {
    return this.text.replace(/(\d)/, this.replacer.bind(this));
    // or return this.text.replace(/(\d)/, (...args) => this.replacer(...args));
  }

  replacer(match, timeString, offset, string) {
    return this.pattern;
  }
}
var v = new MyClass("text 1 2", "X")
console.log(v.run());
Unmitigated
  • 76,500
  • 11
  • 62
  • 80