user5526811
user5526811

Reputation:

Extending RegExp prototype without affecting the original behaviour

I'm creating a lib that extends the RegExp.prototype with assign:

function VerExp() {
  return Object.assign(RegExp.prototype, {
    // my methods here
  });
}

But this is causing a weird behaviour when i try to use the compile function:

const regexp = new VerExp();
// some stuffs....
regexp.compile();

Error:

TypeError: Method RegExp.prototype.compile called on incompatible receiver [object Object]

But, if i create a new instance, extend it and return, will work:

function VerExp() {
  const regexp = new RegExp();
  return Object.assign(regexp, {
    // my methods here
  });
}

const regexp = new VerExp();
regexp.compile();

I would like to understand more the error, why is happening, how could i make it work extending the RegExp prototype, instead of the instance.

Thanks.

Upvotes: 1

Views: 71

Answers (1)

Oriol
Oriol

Reputation: 288220

That's because Object.assign returns the same object the properties were assigned to.

Object.assign(RegExp.prototype, {
    // my methods here
});

will always return RegExp.prototype, so your function doesn't make much sense. All calls will reassign the same properties again and again, and return the same object.

Since RegExp.prototype is not a regex object, attempting to call regex methods on it will throw.

The RegExp prototype object is an ordinary object. It is not a RegExp instance and does not have a [[RegExpMatcher]] internal slot or any of the other internal slots of RegExp instance objects.

What you probably want is subclass RegExp:

class VerExp extends RegExp {
  // my methods here
}
const regexp = new VerExp();
regexp.compile();
console.log("No error");

Upvotes: 1

Related Questions