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

Printing the constructor name for non-plain objects #15

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

DanielSWolf
Copy link

@DanielSWolf DanielSWolf commented Nov 10, 2017

Fixes #14

@@ -8,6 +8,7 @@ var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'f
var setForEach = hasSet && Set.prototype.forEach;
var booleanValueOf = Boolean.prototype.valueOf;
var objectToString = Object.prototype.toString;
var getPrototype = Object.getPrototypeOf || function(o) { return o.__proto__; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the older engines where __proto__ isn't even available?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, __proto__ will be undefined, as will be the result of getPrototype. Consequently, getTypeString will return null (because the result of getPrototype is falsey). And the code will behave as it always has, not printing a type prefix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't a { __proto__: 3 } return 3 in an engine where it's not available?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't a { __proto__: 3 } return 3 in an engine where it's not available?

That will happen even in engines that support __proto__.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ExE-Boss that spec text only treats it as a normal data property when it's not a string, or computed.

({ __proto__: 3 }).__proto__ === Object.prototype returns true in a modern engine, but in, say, IE 8, it returns false.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, in IE 8, ({ __proto__: 3 }).__proto__ returns 3.

index.js Outdated
// Returns the object's constructor name or null if it is a plain object
// or doesn't have a prototype.
function getTypeString(o) {
if (Object.prototype.toString(o) !== '[object Object]') return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want .toString.call(o), otherwise this will always return true

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, my bad. I'll fix this.

&& o.hasOwnProperty('hasOwnProperty')
&& o.hasOwnProperty('isPrototypeOf')
&& o.hasOwnProperty('propertyIsEnumerable')
&& o.hasOwnProperty('toLocaleString')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should these check that they're functions, and ideally, that they behave as expected?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there's anything to be gained by that. Consider that you have an object with own properties hasOwnProperty, isPrototypeOf, etc. Either this is Object.prototype, or it's an object that's trying really hard to look like it. In the latter case, chances are that all those will be functions and that they'll behave correctly.

What's the worst that can happen? The worst case is that you have an object that's trying hard to look like a plain object, and that your library prints it just like a plain object. I don't think that's bad.

After all, this library isn't generating structured information. It's generating a debug string that is supposed to help a developer understand an object graph. And I don't think that anybody will complain if something that's virtually indistinguishable from a plain object is visualized as a plain object.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point. However, to be indistinguishable, this library would have to be unable to distinguish it.

One extreme length we could go to is ensuring not just that they're all functions, but also that Function.prototype.toString.call indicates it's native code, which would work cross-realm.

@codecov
Copy link

codecov bot commented May 26, 2020

Codecov Report

Merging #15 into master will decrease coverage by 2.77%.
The diff coverage is 70.83%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #15      +/-   ##
==========================================
- Coverage   98.14%   95.37%   -2.77%     
==========================================
  Files           2        2              
  Lines         216      238      +22     
  Branches       82       98      +16     
==========================================
+ Hits          212      227      +15     
- Misses          4       11       +7     
Impacted Files Coverage Δ
index.js 95.35% <70.83%> (-2.79%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7cb5c65...12fdb40. Read the comment docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for prototype
3 participants