Skip to content

[bug] new Function string tag is "global" and prototype methods like .bind() are missing. #19651

Closed

Description

@trusktr

I've got a weird issue. First, notice the weird output in the following screenshot, where temp1 is a function created with new Function(...):

screenshot 2018-03-27 at 11 27 25 pm

The string tag appears to be "global" (hence [object global] output) and .bind() is missing!

To reproduce, check out the following repo on the following branch: https://github.com/trusktr/lowclass/tree/nodejs-issue-19651

After cloning and checking out the branch, just run node test.js (there's no dependencies to install) which will result in the output:

> node test.js
es5 mode
es5 mode
about to call super constructor in Dog
WTF? [object global] function false
/home/trusktr/Downloads/src/trusktr+lowclass/src/index.js:387
                descriptor.value = descriptor.value.bind( instance )
                                                    ^

TypeError: descriptor.value.bind is not a function
    at copyDescriptors (/home/trusktr/Downloads/src/trusktr+lowclass/src/index.js:387:53)
    at copyDescriptors (/home/trusktr/Downloads/src/trusktr+lowclass/src/index.js:352:18)
    at getSuperHelperObject (/home/trusktr/Downloads/src/trusktr+lowclass/src/index.js:383:9)
    at superHelper (/home/trusktr/Downloads/src/trusktr+lowclass/src/index.js:368:16)
    at Dog.constructor (/home/trusktr/Downloads/src/trusktr+lowclass/test.js:28:13)
    at new Dog (eval at Class (/home/trusktr/Downloads/src/trusktr+lowclass/src/index.js:135:20), <anonymous>:30:54)
    at Object.<anonymous> (/home/trusktr/Downloads/src/trusktr+lowclass/test.js:35:15)
    at Module._compile (module.js:649:30)
    at Object.Module._extensions..js (module.js:660:10)
    at Module.load (module.js:561:32)

If you look at line 10 of test.js, and make uncomment line 10 and comment the next lines so it look like the following then the error goes away:

    const Clazz = Class
    //const Clazz = Class.configure({
        //mode: 'es5',
        ////mode: 'Reflect.construct',
    //})

So the error is somehow related to the Class.configure call, but I haven't found why though.

As far as I know, I'm not messing with Function.prototype, so I don't see how .bind() could possibly be missing from the function that I am creating. Have I missed something obvious, or is this a bug?

Activity

  1. targos commented on Mar 28, 2018

    @targos
    Member

    It's because of this line: https://github.com/trusktr/lowclass/blob/3854ad9d5f9178afa97c59de08d0909591fa1de0/src/index.js#L176

    NewClass.__proto__ = ParentClass; // static inheritance

    ParentClass is the global object, so the Animal constructor, while being a function, will lose Function.prototype methods there and inherit toString from Object.prototype

  2. TimothyGu commented on Mar 28, 2018

    @TimothyGu
    Member

    Quick analysis:

    _Class.configure returns a function defined by

        return function( ...args ) {
            return Class.call( this, options, ...args )
        }

    This returned function is stored in Clazz. test.js then calls that function in the global scope (const Animal = Clazz(...)), so this is set to global when Clazz is called. This is then reflected in the Class function defined in index.js which has const ParentClass = this || Object, where this is global.

    On the other hand, when const Clazz = Class, Class refers to the _Class function in index.js, and there isn't the Class.call(this) in that function. So the Class is undefined when it is called by _Class.

    Next time, please make sure file this type of issues at nodejs/help when it's not clear that there is a bug in Node.js.

  3. added
    wrong repoIssues that should be opened in another repository.
    on Mar 28, 2018
  4. trusktr commented on Mar 29, 2018

    @trusktr
    ContributorAuthor

    file this type of issues at nodejs/help

    Will do. Sorry about that. I see it now, I forgot a "use strict" in there. Many thanks!

  5. trusktr commented on Mar 29, 2018

    @trusktr
    ContributorAuthor

    I forgot a "use strict" in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionIssues asking questions about Node.js.wrong repoIssues that should be opened in another repository.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions