xregexp icon indicating copy to clipboard operation
xregexp copied to clipboard

Subclass RegExp rather than using __proto__

Open brandonkelly opened this issue 9 years ago • 2 comments

Firefox is giving me this notice in the console when using xregexp:

mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create (xregexp-all.js line 2732)

Referenced line:

regex.__proto__ = XRegExp.prototype;

brandonkelly avatar Apr 05 '16 11:04 brandonkelly

True, but setting __proto__ is quite different than Object.create. Built-in instances like arrays, functions, regex have internal methods. Those methods are not exposed through the prototype chain. In other words you can not extend built ins prior ES6. http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/ Setting __proto__ changes the internal state of the [[Prototype]] property, but it keeps other internal states.

In the other hand Object.create always returns native object. If you try to do: var regex = Object.create(/^regex$/), the returned object is not exactly regex since it doesn't have internal methods and properties of a real regex instance.

abozhilov avatar Apr 05 '16 12:04 abozhilov

@abozhilov described why this is used. You can't subclass builtins like RegExp prior to ES6 (ES 2015).

In fact XRegExp already has an alternative/fallback for browsers that don't support __proto__. See here. But that is actually slower, rather than the hypothetical perf hit described in the console message. (I'm not seeing this message in Firefox, BTW. @brandonkelly, is it still being shown for you?)

In fact you could remove all related code and everything would still work. XRegExp doesn't actually add anything to XRegExp.prototype. The point of this code is just so that developers using XRegExp can add to XRegExp.prototype if they wish.

It would be nice to start using true RegExp subclassing for this in browsers that support it. Then the use of __proto__ could be removed entirely, and the existing fallback of copying over properties from XRegExp.prototype could cover all non ES 2015 browsers. Subclassing of RegExp can't be transpiled to pre ES 2015 code though, so this should probably wait for at least somewhat broader native adoption.

slevithan avatar May 15 '16 10:05 slevithan