<h2 dir="auto">Bug Report</h2>

<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I would like to work on a fix!</li>
</ul>
<p dir="auto"><strong>Current Behavior</strong><br>
<code class="notranslate">_objectWithoutProperties</code> is being called directly on deeply nested destructured property chains without taking default values into account. This causes <code class="notranslate">TypeError: Cannot read property 'X' of undefined</code> errors being thrown in a code that uses fallback values to guards against missing nested properties.<br>
The strange thing is that issue only happens for a specific environment set - <code class="notranslate">Chrome &gt;= 61, Firefox &gt;= 60, Opera &gt;= 48, Safari &gt;= 11, Edge &gt;= 16, ChromeAndroid &gt;= 77, iOS &gt;= 11</code>.<br>
I have thought that it may be some optimization/minimization/mangling issue, however, it seems that the root cause is somewhere within the babel-preset-env. Default parameter assignments seem to be dropped when object-destructuring, but not the object rest operator, is supported on the selected platform/env.</p>
<p dir="auto"><strong>Input Code</strong></p>
<ul dir="auto">
<li>The full case for reproduction <a href="https://babeljs.io/repl#?browsers=Chrome%20%3E%3D%2061%2C%20Firefox%20%3E%3D%2060%2C%20Opera%20%3E%3D%2048%2C%20Safari%20%3E%3D%2011%2C%20Edge%20%3E%3D%2016%2C%20ChromeAndroid%20%3E%3D%2077%2C%20iOS%20%3E%3D%2011&amp;build=&amp;builtIns=false&amp;spec=false&amp;loose=false&amp;code_lz=MYGwhgzhAEDC5WgbwFDWgcwKYBdO5ywCcAKASmTXWmAHsA7CPVa6gMwEsimAZLANywgA8mwByWJh3oYAXJVasIWOvQAmfQSPGSc0uQsVLaAWywAFIrQAOxHAE8ANFSPoAdB6K6XigL7QAXmRfH3R_IKQQ1nDoHAALDggAbhQfLxwAVyJ6aC8mFLCUXxSUVSZoaSYwemAsQPR6LAB3OAQIchSy2hAsNxBaDBJKnGrat2wcQiIyErK8NnqSFmhObhxNIVEJKRl5ZfRlVQ0BTZ0dg33qCFMLK1siB2cjDzc8nB8YyKpPkN8KAIAfLldLMGNcen0BiQ2Es_jMgA&amp;debug=false&amp;forceAllTransforms=false&amp;shippedProposals=false&amp;circleciRepo=&amp;evaluate=true&amp;fileSize=false&amp;timeTravel=false&amp;sourceType=module&amp;lineWrap=true&amp;presets=env%2Cenv&amp;prettier=false&amp;targets=&amp;version=7.8.4&amp;externalPlugins=" rel="nofollow">is available on the REPL</a>. Please disable the ENV PRESET &gt; Enabled checkbox to see the code running properly when the legacy transforms apply and thus default values are applied.</li>
</ul>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Class {
  get getter() {
    const {
      firstLevelOfNesting: {
        secondLevelOfNesting: {
          someProperty,
          ...rest
        } = {}
      } = {}
    } = this;

    return rest;
  }
};"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">Class</span> <span class="pl-kos">{</span>
  <span class="pl-k">get</span> <span class="pl-en">getter</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-kos">{</span>
      <span class="pl-c1">firstLevelOfNesting</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">secondLevelOfNesting</span>: <span class="pl-kos">{</span>
          someProperty<span class="pl-kos">,</span>
          ...<span class="pl-s1">rest</span>
        <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
      <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
    <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-c1">this</span><span class="pl-kos">;</span>

    <span class="pl-c1">return</span><span class="pl-kos"></span> <span class="pl-c1">rest</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">This code generates the following output code when preset-env is not used:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var _this$firstLevelOfNes = this.firstLevelOfNesting;
      _this$firstLevelOfNes = _this$firstLevelOfNes === void 0 ? {} : _this$firstLevelOfNes;
      var _this$firstLevelOfNes2 = _this$firstLevelOfNes.secondLevelOfNesting;
      _this$firstLevelOfNes2 = _this$firstLevelOfNes2 === void 0 ? {} : _this$firstLevelOfNes2;

      var someProperty = _this$firstLevelOfNes2.someProperty,
          rest = _objectWithoutProperties(_this$firstLevelOfNes2, [&quot;someProperty&quot;]);"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-s1">_this$firstLevelOfNes</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">firstLevelOfNesting</span><span class="pl-kos">;</span>
      <span class="pl-s1">_this$firstLevelOfNes</span> <span class="pl-c1">=</span> <span class="pl-s1">_this$firstLevelOfNes</span> <span class="pl-c1">===</span> <span class="pl-k">void</span> <span class="pl-c1">0</span> ? <span class="pl-kos">{</span><span class="pl-kos">}</span> : <span class="pl-s1">_this$firstLevelOfNes</span><span class="pl-kos">;</span>
      <span class="pl-k">var</span> <span class="pl-s1">_this$firstLevelOfNes2</span> <span class="pl-c1">=</span> <span class="pl-s1">_this$firstLevelOfNes</span><span class="pl-kos">.</span><span class="pl-c1">secondLevelOfNesting</span><span class="pl-kos">;</span>
      <span class="pl-s1">_this$firstLevelOfNes2</span> <span class="pl-c1">=</span> <span class="pl-s1">_this$firstLevelOfNes2</span> <span class="pl-c1">===</span> <span class="pl-k">void</span> <span class="pl-c1">0</span> ? <span class="pl-kos">{</span><span class="pl-kos">}</span> : <span class="pl-s1">_this$firstLevelOfNes2</span><span class="pl-kos">;</span>

      <span class="pl-k">var</span> <span class="pl-s1">someProperty</span> <span class="pl-c1">=</span> <span class="pl-s1">_this$firstLevelOfNes2</span><span class="pl-kos">.</span><span class="pl-c1">someProperty</span><span class="pl-kos">,</span>
          <span class="pl-s1">rest</span> <span class="pl-c1">=</span> <span class="pl-en">_objectWithoutProperties</span><span class="pl-kos">(</span><span class="pl-s1">_this$firstLevelOfNes2</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">"someProperty"</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">The <code class="notranslate">=== void 0 ? {} :</code> expressions apply the fallback values before following code extracts nested properties. However, this is not the case when <code class="notranslate">preset-env</code> is applied with the mentioned browser list:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const {
      firstLevelOfNesting: {
        secondLevelOfNesting: {
          someProperty
        } = {}
      } = {}
    } = this,
          rest = _objectWithoutProperties(this.firstLevelOfNesting.secondLevelOfNesting, [&quot;someProperty&quot;]);"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-kos">{</span>
      <span class="pl-c1">firstLevelOfNesting</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">secondLevelOfNesting</span>: <span class="pl-kos">{</span>
          someProperty
        <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
      <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
    <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">,</span>
          <span class="pl-s1">rest</span> <span class="pl-c1">=</span> <span class="pl-en">_objectWithoutProperties</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">firstLevelOfNesting</span><span class="pl-kos">.</span><span class="pl-c1">secondLevelOfNesting</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">"someProperty"</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">As you can see the destructured property chain is evaluated in-place without taking default values into account <code class="notranslate">this.firstLevelOfNesting.secondLevelOfNesting</code> - this causes the cannot read property X of undefined errors being thrown.<br>
The issue also affects argument destructuring of plain functions. A single level of nesting is not affected due to <code class="notranslate">_objectWithoutProperties</code> handling <code class="notranslate">undefined</code>/<code class="notranslate">null</code> case on its own.</p>
<p dir="auto"><strong>Expected behavior/code</strong><br>
The code with the specific browser list applied should behave like the code without preset-env applied and match native implementation (the code below, after pasting into Chrome DevTools, should not throw):</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Class {
  get getter() {
    const {
      firstLevelOfNesting: {
        secondLevelOfNesting: {
          someProperty,
          ...rest
        } = {}
      } = {}
    } = this;

    return rest;
  }
};

const instance =  new Class();
console.log(instance.getter);

const f = ({
  firstLevelOfNesting: {
    secondLevelOfNesting: {
      someProperty,
      ...rest
    } = {}
  } = {}
}) =&gt; rest;

console.log(f({}));"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">Class</span> <span class="pl-kos">{</span>
  <span class="pl-k">get</span> <span class="pl-en">getter</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">const</span> <span class="pl-kos">{</span>
      <span class="pl-c1">firstLevelOfNesting</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">secondLevelOfNesting</span>: <span class="pl-kos">{</span>
          someProperty<span class="pl-kos">,</span>
          ...<span class="pl-s1">rest</span>
        <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
      <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
    <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-c1">this</span><span class="pl-kos">;</span>

    <span class="pl-c1">return</span><span class="pl-kos"></span> <span class="pl-c1">rest</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">instance</span> <span class="pl-c1">=</span>  <span class="pl-k">new</span> <span class="pl-v">Class</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">instance</span><span class="pl-kos">.</span><span class="pl-c1">getter</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">f</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">firstLevelOfNesting</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">secondLevelOfNesting</span>: <span class="pl-kos">{</span>
      someProperty<span class="pl-kos">,</span>
      ...<span class="pl-s1">rest</span>
    <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
  <span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">rest</span><span class="pl-kos">;</span>

<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">f</span><span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Babel Configuration (babel.config.js, .babelrc, package.json#babel, cli command, .eslintrc)</strong></p>
<ul dir="auto">
<li><code class="notranslate">preset-env</code> with the following browser list <code class="notranslate">Chrome &gt;= 61, Firefox &gt;= 60, Opera &gt;= 48, Safari &gt;= 11, Edge &gt;= 16, ChromeAndroid &gt;= 77, iOS &gt;= 11</code>:</li>
</ul>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="[
  'Chrome &gt;= 61',
  'Firefox &gt;= 60',
  'Opera &gt;= 48',
  'Safari &gt;= 11',
  'Edge &gt;= 16',
  'ChromeAndroid &gt;= 77',
  'iOS &gt;= 11'
]"><pre class="notranslate"><span class="pl-kos">[</span>
  <span class="pl-s">'Chrome &gt;= 61'</span><span class="pl-kos">,</span>
  <span class="pl-s">'Firefox &gt;= 60'</span><span class="pl-kos">,</span>
  <span class="pl-s">'Opera &gt;= 48'</span><span class="pl-kos">,</span>
  <span class="pl-s">'Safari &gt;= 11'</span><span class="pl-kos">,</span>
  <span class="pl-s">'Edge &gt;= 16'</span><span class="pl-kos">,</span>
  <span class="pl-s">'ChromeAndroid &gt;= 77'</span><span class="pl-kos">,</span>
  <span class="pl-s">'iOS &gt;= 11'</span>
<span class="pl-kos">]</span></pre></div>
<p dir="auto"><strong>Environment</strong></p>
<ul dir="auto">
<li>Babel version(s): [7.8.4]</li>
<li>Node/npm version: [Node 12.14.0/npm 6.13.4]</li>
<li>OS: [Windows 10]</li>
<li>Monorepo: [no]</li>
<li>How you are using Babel: [<code class="notranslate">loader</code>, <code class="notranslate">REPL</code>]</li>
</ul>
<blockquote>
<p dir="auto">Issue originally made by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/milankinen/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/milankinen">@milankinen</a></p>
</blockquote>
<h3 dir="auto">Bug information</h3>
<ul dir="auto">
<li><strong>Babel version:</strong> 6.6.0</li>
<li><strong>Node version:</strong> 4.2.0</li>
<li><strong>npm version:</strong> 2.14.7</li>
</ul>
<h3 dir="auto">Options</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="--presets es2015"><pre class="notranslate"><code class="notranslate">--presets es2015
</code></pre></div>
<h3 dir="auto">Description</h3>
<p dir="auto">Default parameters seem to be broken in the newest babel 6.6.0 release, at least in arrow functions.</p>
<p dir="auto">If I run the following code:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="npm i babel-cli@6.6.0 babel-preset-es2015@6.6.0
echo 'export const f = (p1, p2 = &quot;tsers&quot;) =&gt; p1 + p2' | ./node_modules/.bin/babel --presets es2015"><pre class="notranslate"><code class="notranslate">npm i babel-cli@6.6.0 babel-preset-es2015@6.6.0
echo 'export const f = (p1, p2 = "tsers") =&gt; p1 + p2' | ./node_modules/.bin/babel --presets es2015
</code></pre></div>
<p dir="auto">I'll get the following output:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&quot;use strict&quot;;

var _arguments = arguments;
Object.defineProperty(exports, &quot;__esModule&quot;, {
  value: true
});
var f = exports.f = function f(p1) {
  var p2 = _arguments.length &lt;= 1 || _arguments[1] === undefined ? &quot;tsers&quot; : _arguments[1];
  return p1 + p2;
};"><pre class="notranslate"><code class="notranslate">"use strict";

var _arguments = arguments;
Object.defineProperty(exports, "__esModule", {
  value: true
});
var f = exports.f = function f(p1) {
  var p2 = _arguments.length &lt;= 1 || _arguments[1] === undefined ? "tsers" : _arguments[1];
  return p1 + p2;
};
</code></pre></div>
<p dir="auto">As you can see, the second default argument "p2" is taken from "_arguments" instead of "arguments" which is not correct.</p>
<p dir="auto">I'd appreciate a quick fix because this bug appears also in older 6.x "high level" babel releases due to semver transient dependency definitions, i.e. also the following code causes the same invalid output:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="npm i babel-cli@6.5.x babel-preset-es2015@6.5.x
echo 'export const f = (p1, p2 = &quot;tsers&quot;) =&gt; p1 + p2' | ./node_modules/.bin/babel --presets es2015
"><pre class="notranslate"><code class="notranslate">npm i babel-cli@6.5.x babel-preset-es2015@6.5.x
echo 'export const f = (p1, p2 = "tsers") =&gt; p1 + p2' | ./node_modules/.bin/babel --presets es2015

</code></pre></div>
<p dir="auto">EDIT:<br>
I tried to run the code without "exports" keyword and it works ok:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="echo 'const f = (p1, p2 = &quot;tsers&quot;) =&gt; p1 + p2' | ./node_modules/.bin/babel --presets es2015 "><pre class="notranslate"><code class="notranslate">echo 'const f = (p1, p2 = "tsers") =&gt; p1 + p2' | ./node_modules/.bin/babel --presets es2015 
</code></pre></div>
<p dir="auto">Will transform into:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&quot;use strict&quot;;

var f = function f(p1) {
  var p2 = arguments.length &lt;= 1 || arguments[1] === undefined ? &quot;tsers&quot; : arguments[1];
  return p1 + p2;
};"><pre class="notranslate"><code class="notranslate">"use strict";

var f = function f(p1) {
  var p2 = arguments.length &lt;= 1 || arguments[1] === undefined ? "tsers" : arguments[1];
  return p1 + p2;
};
</code></pre></div>