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
Derived constructors should not be allowed to return primitives #13571
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 6f975ee:
|
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/47406/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me.
...l-plugin-transform-classes/test/fixtures/spec/derived-constructor-must-call-super-5/index.js
Outdated
Show resolved
Hide resolved
...el-plugin-transform-classes/test/fixtures/spec/derived-constructor-must-call-super-5/exec.js
Outdated
Show resolved
Hide resolved
Hi @fedeci thanks for your comments, I've resolved them, please consider re-reviewing it. I'm not sure why my prettier on my local isn't running, I'll have to check that out. |
It is not running because those are strings and not "real lines of code". If I am not wrong we started moving the helpers to individual files so that eslint and prettier could work. |
if (typeof call === "object" || typeof call === "function") { | ||
return call; | ||
} else { | ||
throw new TypeError("Invalid attempt to return primitive value"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts on matching v8's error?
throw new TypeError("Invalid attempt to return primitive value"); | |
throw new TypeError("Derived constructors may only return object or undefined"); |
if (call) { | ||
if (typeof call === "object" || typeof call === "function") { | ||
return call; | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic doesn't work if the constructor returns, for example, 0
or null
(can you add a test for a falsy value?).
It should be something like
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("...");
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or
if (call !== void 0) {
if (typeof call === "object" || typeof call === "function") {
return call;
} else {
// throw errors
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My version is 3 bytes shorter when using terser 😛
function f(o){if(o&&("object"==typeof o||"function"==typeof o))return o;if(void 0!==o)throw new TypeError("...")}
function g(o){if(void 0!==o){if("object"==typeof o||"function"==typeof o)return o;throw new TypeError("...")}}
Also, I think yours incorrectly allows returning null
.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but use of 'typeof' is a bad idea and kill perf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you suggest to use instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well. 'typeof obj === 'object';' is almost ~50% slower than other 'typeof'. And 'typeof number' return NaN even if it's not an number - in some cases.
There exist 2 popular utility libraries that has an optimized check for this.
Personally I would have used some kind of meta data and bitwise masks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There exist 2 popular utility libraries that has an optimized check for this.
I only found is-object
(which still uses typeof === "object"
) and lodash.isObject
(which also uses typeof
and checks if it's "object"
). Why would typeof === "object"
be slower than the other types?
Personally I would have used some kind of meta data and bitwise masks
o
can be any possible JS value present in the JS code of our users, we cannot use bitwise mask
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot the history behind this, but AngularJS had some good checks in their earlier versions. 1x of their library. I think they checked against the constructor. Also Google had a library a few years back - forgot the name - with fast checks.
if (call) { | ||
if (typeof call === "object" || typeof call === "function") { | ||
return call; | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 'else' is not needed. You already return in the line above.
Derived constructor won't be allowed to return primitive values