Node: (function() {}).toString() yields different results in node 10.0.0 vs node 9

Created on 2 May 2018  Â·  13Comments  Â·  Source: nodejs/node

  • Version: Node 10.0.0
  • Platform: Debian GNU/Linux 8.10 (jessie)

Node 10.0.0 yields an unexpected result when functions are converted to strings through the toString method. Here's what happens:

  • 10.0.0: (function () { }).toString() results in: 'function () { }'.
  • 9.5.0: (function(){ }).toString() results in: 'function (){ }'.

This difference seems insignificant, but it affects several critical NPM modules. One example is: promisify-node, here's a relevant issue that I created in that repo: https://github.com/nodegit/promisify-node/issues/28

Of course, this means that many other NPM repos are being affected, such as: nodegit. Here's the issue I created for them: https://github.com/nodegit/nodegit/issues/1490

Within the other affected modules, we have: nodegit-promise, asap, fbjs, eslint-plugin-react, and so on and so forth.

V8 Engine

Most helpful comment

To provide some balance to the current feedback, I should mention that this change also can be an improvement for some packages. With jsdom, it means that we can better match other browsers (and continue to do so with Chrome), where we've previously failed some tests due to differences in the expected function-to-string results.

All 13 comments

See https://github.com/nodejs/node/issues/20355 for some previous context … I guess if it turns out that the ecosystem impact is too large, we may want to look into amending this language feature change.

@nodejs/v8

dupe of https://github.com/nodejs/node/issues/20355

the new output is something any proper regex should catch anyway, the bug you linked is a bug without this change.

@devsnek that is true, but this issue is relevant to many packages. At least we can help the authors and other developers know what's causing their builds to fail, and how to aid in the solution to this problem.

To provide some balance to the current feedback, I should mention that this change also can be an improvement for some packages. With jsdom, it means that we can better match other browsers (and continue to do so with Chrome), where we've previously failed some tests due to differences in the expected function-to-string results.

Thank you @Zirro 🙌

@sadasant - I see different inputs resulting in different outputs. No surprise there. Perhaps the "Here's what happens" section should include 4 inputs and outputs starting with --

10.0.0: (function () { }).toString() results in: 'function () { }'.
9.5.0: (function () { }).toString() results in: ?

10.0.0: (function(){ }).toString() results in: ?.
9.5.0: (function(){ }).toString() results in: 'function (){ }'.

  • Version: Node 10.0.0
  • Platform: Windows 10 x64

This is what I have in Node 10, and truly believe that this is 100% is right result:

> (function(){ }).toString()
'function(){ }'
> (function (){ }).toString()
'function (){ }'
> (function (){}).toString()
'function (){}'
> (function(){}).toString()
'function(){}'
>

Just as a quick data point - I’m one of the core contributors to the Unexpected project which is an extensible assertion framework and we have also been affected.

While we already used a regex when we inspect functions this caught us out as well and it needed a modification - we will get a fix out shortly.

So, Node 10.0.0 is fully filled in, but Node 9.5.0 is not, so dependent projects don't quite know what's changed, nor therefore what to fix or look for in their code.

_Edited to fill in missing 9.3.0 outputs (thanks, @nmain) --_

INPUT|10.0.0 OUTPUT|9.3.0 OUTPUT|change
:-----:|:-----:|:-----:|:-----:
(function(){ }).toString()|function(){ }|function (){ }|y
(function(){}).toString()|function(){}|function (){}|y
(function (){ }).toString()|function (){ }|function (){ }|n
(function (){}).toString()|function (){}|function (){}|n

@TallTed

C:\Users\nmain>node -v
v9.3.0

C:\Users\nmain>node
> (function(){ }).toString()
'function (){ }'
> (function (){ }).toString()
'function (){ }'
> (function (){}).toString()
'function (){}'
> (function(){}).toString()
'function (){}'
>

Thanks, @nmain. Filled in my earlier table.

@TallTed the documentation change you mentioned sounds good!
@alexjeffburke thank you! Keep up the good work!

Seems like this can be closed at this point. I don't think there's any plans to change the behavior in 10.x etc. If I'm wrong, by all means, re-open. Closing for now. Thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

loretoparisi picture loretoparisi  Â·  3Comments

filipesilvaa picture filipesilvaa  Â·  3Comments

Brekmister picture Brekmister  Â·  3Comments

willnwhite picture willnwhite  Â·  3Comments

vsemozhetbyt picture vsemozhetbyt  Â·  3Comments