From 72965179580903ec9d28fb73b67f4d4717b60f63 Mon Sep 17 00:00:00 2001 From: Alberto Piai Date: Tue, 20 Sep 2016 18:19:09 +0200 Subject: [PATCH] Fix `typeof Symbol.prototype` (#3686) * 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: https://github.com/zloirock/core-js/issues/189#issuecomment-209864582). --- packages/babel-helpers/src/helpers.js | 6 +++++- .../test/fixtures/symbols/shadow/expected.js | 2 +- .../test/fixtures/symbols/typeof/exec.js | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index d57afc018833..000360432f2b 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -8,7 +8,11 @@ export default helpers; helpers.typeof = template(` (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") ? function (obj) { return typeof obj; } - : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; + : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype + ? "symbol" + : typeof obj; + }; `); helpers.jsx = template(` diff --git a/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/shadow/expected.js b/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/shadow/expected.js index 0e6479c44558..2980b2f49cf0 100644 --- a/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/shadow/expected.js +++ b/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/shadow/expected.js @@ -1,4 +1,4 @@ -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _Symbol = foo(); typeof s === "undefined" ? "undefined" : _typeof(s); diff --git a/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/typeof/exec.js b/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/typeof/exec.js index 0c53760815a1..d89051afe7db 100644 --- a/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/typeof/exec.js +++ b/packages/babel-plugin-transform-es2015-typeof-symbol/test/fixtures/symbols/typeof/exec.js @@ -1,3 +1,4 @@ var s = Symbol("s"); assert.equal(typeof s, "symbol"); assert.ok(typeof s === "symbol"); +assert.ok(typeof Symbol.prototype === 'object', "`typeof Symbol.prototype` should be 'object'");