Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
trusktr opened this issue Mar 28, 2018 · 4 comments
Labels
question Issues that look for answers. wrong repo Issues that should be opened in another repository.

Comments

@trusktr
Copy link
Contributor

trusktr commented Mar 28, 2018

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?

@targos
Copy link
Member

targos commented Mar 28, 2018

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

@TimothyGu TimothyGu added the question Issues that look for answers. label Mar 28, 2018
@TimothyGu
Copy link
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.

@ChALkeR ChALkeR added the wrong repo Issues that should be opened in another repository. label Mar 28, 2018
@trusktr
Copy link
Contributor Author

trusktr commented Mar 29, 2018

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!

@trusktr
Copy link
Contributor Author

trusktr commented Mar 29, 2018

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
Labels
question Issues that look for answers. wrong repo Issues that should be opened in another repository.
Projects
None yet
Development

No branches or pull requests

4 participants