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
Fix typeof Symbol.prototype
#3686
Conversation
Babel uses a helper function to return the correct value for `typeof obj` when obj is a Symbol and support for Symbol has been polyfilled. This function assumes that `obj.constructor === Symbol` implies `typeof obj === 'symbol'`. This isn't true when obj is `Symbol.prototype`. In that case (REPL from node 6, the same holds in Firefox): ``` > Symbol.prototype.constructor === Symbol true > typeof Symbol.prototype 'object' > ``` AFAICS, that's the only case where the assumption doesn't hold. The test added by this patch fails only on node 0.10, as 0.12 already has a native implementation of Symbol and the polyfill code doesn't run. This caused a problem in core-js when it's compiled with babel (the issue was isolated by @skozin here: zloirock/core-js#189 (comment)).
Current coverage is 88.28% (diff: 100%)
|
I just tested it in chrome and the babel repl. |
This'll also happen anywhere we test typeof on an object that points to var obj = Object.create(Symbol.prototype);
console.log(typeof obj); // => "symbol" |
Thanks! I'm happy to contribute, we rely a lot on babel. Good point. We would in theory be able to polyfill
(or the equivalent This would be possible if the runtime polyfills for Symbol (e.g. the one provided by core-js) could be implemented in such a way that
for a polyfilled Symbol. To do that, we could split the exposed global Symbol and Symbol.prototype from the internal ones used to create the instances (make copies, so that === checks fail): this would fix the instanceof (and equivalent isPrototypeOf) checks above. The problem with that is that we would still not achieve the following:
We would fix the former, but the latter would then change to return false (in current polyfills, both are true). So if we do that we'd also have to replace the global Do you think this is even doable safely? Worth it? If not, we'll have to accept that Symbol cannot be polyfilled completely, and teach people to only use a safe subset of Symbol if their code has to run on polyfilled implementations. (This PR is then not achieving full correctness, but fixing one case that I have seen used and is currently broken when compiled through babel) |
I think it should be merged urgently. |
* formatting * fix `typeof Symbol.prototype` Babel uses a helper function to return the correct value for `typeof obj` when obj is a Symbol and support for Symbol has been polyfilled. This function assumes that `obj.constructor === Symbol` implies `typeof obj === 'symbol'`. This isn't true when obj is `Symbol.prototype`. In that case (REPL from node 6, the same holds in Firefox): ``` > Symbol.prototype.constructor === Symbol true > typeof Symbol.prototype 'object' > ``` AFAICS, that's the only case where the assumption doesn't hold. The test added by this patch fails only on node 0.10, as 0.12 already has a native implementation of Symbol and the polyfill code doesn't run. This caused a problem in core-js when it's compiled with babel (the issue was isolated by @skozin here: zloirock/core-js#189 (comment)).
fix
typeof Symbol.prototype
Babel uses a helper function to return the correct value for
typeof obj
when obj is a Symbol and support for Symbol has been polyfilled.This function assumes that
obj.constructor === Symbol
impliestypeof obj === 'symbol'
.This isn't true when obj is
Symbol.prototype
. In that case (REPL fromnode 6, the same holds in Firefox):
AFAICS, that's the only case where the assumption doesn't hold.
The test added by this patch fails only on node 0.10, as 0.12 already
has a native implementation of Symbol and the polyfill code doesn't run.
This caused a problem in core-js when it's compiled with babel (the
issue was isolated by @skozin here:
zloirock/core-js#189 (comment)).