Skip to content

isPlainObject() throws TypeError in v2.2.1, but not in v1.11.1 #2982

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

Closed
codeworrior opened this issue Mar 10, 2016 · 4 comments
Closed

isPlainObject() throws TypeError in v2.2.1, but not in v1.11.1 #2982

codeworrior opened this issue Mar 10, 2016 · 4 comments

Comments

@codeworrior
Copy link

Hi,
when migrating our code from jQuery 1.11.1 to jQuery 2.2.1, we found a difference between the jQuery.isPlainObject implementations in the two versions. This difference also affects other jQuery methods that internally call isPlainObject, like jQuery.extend.

See https://jsfiddle.net/tjmgfjg4/1/ for a reduced example with jQuery.extend.

The reason seems to be that 3dccf62 removed the try ... catch around the following check in isPlainObject:

        if ( obj.constructor &&
                !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }

When isPlainObject is called for an object which has a constructor property with a non-falsy, non-function value, it now throws a TypeError ("Cannot convert undefined or null to object").

I understand that using a property constructor with a value other than the original constructor function is somewhat 'unusual' and not best practice. But as far as I can see, this is not prohibited by an Ecmascript spec (up to and including ES2015). I also understand that it is discussable whether such objects should be reported as plain or not. But running into a TypeError seems quite unexpected.

Adding the try ... catch back might not be the best way to fix this. But maybe the check could be made more robust by some other mean, e.g. adding another condition (motivated by the concrete error)

        if ( obj.constructor &&
                typeof obj.constructor.prototype === 'object' &&
                !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }

or by checking whether obj.constructor is of type function (motivated by the original intention: check whether the standard constructorbacklink points to Object)

        if ( typeof obj.constructor === 'function' &&
                !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }

Please let me know your thoughts about this: regression or valid simplification?

Kind Regards, cw

@dmethvin
Copy link
Member

This is a dup of #2968, it should be fixed in master already and in our next patch release.

@codeworrior
Copy link
Author

Thanks for looking into this.

Maybe I should have mentioned that I read and checked #2968 already, as well as its fixes. Unfortunately, they don't fix the issue that I described above.

See https://jsfiddle.net/tjmgfjg4/3/ which now uses a copy of the current isPlainObject (from 2.2-stable)

I don't mind if you want to merge this with #2968, but please re-open it.

Regards, cw

@dmethvin
Copy link
Member

You're right, it's a different edge case! We can guard against a funny constructor property I suppose.

@dmethvin dmethvin reopened this Mar 11, 2016
@mgol
Copy link
Member

mgol commented Mar 11, 2016

I like the idea of checking if constructor is of the fuction type.

gibson042 added a commit to gibson042/jquery that referenced this issue Mar 11, 2016
@mgol mgol added this to the 1.12.2/2.2.2 milestone Mar 11, 2016
@mgol mgol added the Core label Mar 11, 2016
timmywil pushed a commit that referenced this issue Mar 14, 2016
- Guard isPlainObject against inherited scalar constructors

Fixes gh-2982
Close gh-2985
@lock lock bot locked as resolved and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

5 participants