<h3 dir="auto">Input Code</h3>
<p dir="auto">The following test suite describes the issue:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import {expect} from 'chai';

class Demo {
  bad = async (x) =&gt; arguments[0];
  good = (x) =&gt; (async () =&gt; (x))();
}

describe('async bound handlers', function() {
  lazy('demo', () =&gt; new Demo('Scope leak!'));

  describe('#bad', function() {
    it('does bad things', async function() {
      const leak = await this.demo.bad(123);
      expect(leak).to.equal('Scope leak!');
    });
  });

  describe('#good', function() {
    it('does good things', async function() {
      const x = await this.demo.good(123);
      expect(x).to.equal(123);
    });
  });
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-s1">expect</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'chai'</span><span class="pl-kos">;</span>

<span class="pl-k">class</span> <span class="pl-v">Demo</span> <span class="pl-kos">{</span>
  <span class="pl-c1">bad</span> <span class="pl-c1">=</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">arguments</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
  <span class="pl-c1">good</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-s1">x</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>

<span class="pl-en">describe</span><span class="pl-kos">(</span><span class="pl-s">'async bound handlers'</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-en">lazy</span><span class="pl-kos">(</span><span class="pl-s">'demo'</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-k">new</span> <span class="pl-v">Demo</span><span class="pl-kos">(</span><span class="pl-s">'Scope leak!'</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-en">describe</span><span class="pl-kos">(</span><span class="pl-s">'#bad'</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-en">it</span><span class="pl-kos">(</span><span class="pl-s">'does bad things'</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-k">function</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">leak</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">demo</span><span class="pl-kos">.</span><span class="pl-en">bad</span><span class="pl-kos">(</span><span class="pl-c1">123</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
      <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">leak</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">to</span><span class="pl-kos">.</span><span class="pl-en">equal</span><span class="pl-kos">(</span><span class="pl-s">'Scope leak!'</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><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-en">describe</span><span class="pl-kos">(</span><span class="pl-s">'#good'</span><span class="pl-kos">,</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-en">it</span><span class="pl-kos">(</span><span class="pl-s">'does good things'</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-k">function</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">x</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">demo</span><span class="pl-kos">.</span><span class="pl-en">good</span><span class="pl-kos">(</span><span class="pl-c1">123</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
      <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">to</span><span class="pl-kos">.</span><span class="pl-en">equal</span><span class="pl-kos">(</span><span class="pl-c1">123</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><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>
<h3 dir="auto">Babel Configuration (.bablerc, package.json, cli command)</h3>
<p dir="auto">Using <a href="https://github.com/babel/broccoli-babel-transpiler">broccoli-babel-transpiler</a> with the following options:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  nonStandard: true,
  moduleIds: false,
  modules: 'system',
  externalHelpers: true,
  stage: 0,
  // …other project-specific configuration (extensions, directories, etc)
}"><pre class="notranslate"><span class="pl-kos">{</span>
  <span class="pl-c1">nonStandard</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
  <span class="pl-c1">moduleIds</span>: <span class="pl-c1">false</span><span class="pl-kos">,</span>
  <span class="pl-c1">modules</span>: <span class="pl-s">'system'</span><span class="pl-kos">,</span>
  <span class="pl-c1">externalHelpers</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
  <span class="pl-c1">stage</span>: <span class="pl-c1">0</span><span class="pl-kos">,</span>
  <span class="pl-c">// …other project-specific configuration (extensions, directories, etc)</span>
<span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Expected Behavior</h3>
<p dir="auto">When defining a bound async function within an ES6 class, like so:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Demo {
  hello = async (name) =&gt; `Hello, ${name}!`;
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">Demo</span> <span class="pl-kos">{</span>
  <span class="pl-c1">hello</span> <span class="pl-c1">=</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-s">`Hello, <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">name</span><span class="pl-kos">}</span></span>!`</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">I would expect <code class="notranslate">name</code> to be defined.</p>
<h3 dir="auto">Current Behavior</h3>
<p dir="auto">With the above example given for <em>expected behavior</em>, the value of <code class="notranslate">name</code> is bound to the first argument given to the constructor for <code class="notranslate">Demo</code>.</p>
<h3 dir="auto">Possible Solution</h3>
<p dir="auto">A workaround is to declare the bound function <em>without</em> the <code class="notranslate">async</code> keyword, and have it return a self-evaluating function <em>with</em> the <code class="notranslate">async</code> keyword containing the original logic. For example:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Demo {
  hello = (name) =&gt; (async () =&gt; `Hello, ${name}!`)();
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">Demo</span> <span class="pl-kos">{</span>
  <span class="pl-c1">hello</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">name</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-s">`Hello, <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">name</span><span class="pl-kos">}</span></span>!`</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">A possible solution might be for Babel to do this automatically.</p>
<h3 dir="auto">Context</h3>
<p dir="auto">In practice, our React project passes bound functions as callbacks (e.g: <code class="notranslate">onClick</code>). Rather than dynamically binding these using <code class="notranslate">::</code> or <code class="notranslate">Function#bind</code>, which create new objects that violate shallow prop comparisons and trigger needless re-rendering (see <a href="http://benchling.engineering/performance-engineering-with-react/#functionbindinlineanonymousfunctions" rel="nofollow">Performance Engineering with React</a>), we bind these using the pattern discussed here.</p>
<p dir="auto">A fair number of our handler functions have asynchronous behavior, and we'd like to take advantage of the <code class="notranslate">async</code> keyword as we have with our unbound class functions. The obvious way to do this is to declare the assigned function to have the <code class="notranslate">async</code> keyword, which triggers the errant behavior.</p>
<p dir="auto">In short, we want the <code class="notranslate">job</code> variable in both functions declared below to be consistent:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Demo {
  async performAsync(job) {/*…process the given job…*/}
  boundPerformAsync = async (job) =&gt; {/*…process the given job…*/}
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">Demo</span> <span class="pl-kos">{</span>
  <span class="pl-k">async</span> <span class="pl-en">performAsync</span><span class="pl-kos">(</span><span class="pl-s1">job</span><span class="pl-kos">)</span> <span class="pl-kos">{</span><span class="pl-c">/*…process the given job…*/</span><span class="pl-kos">}</span>
  <span class="pl-c1">boundPerformAsync</span> <span class="pl-c1">=</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-s1">job</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span><span class="pl-c">/*…process the given job…*/</span><span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><code class="notranslate">this.performAsync(job)</code> and <code class="notranslate">this.boundPerformAsync(job)</code> should be functionally equivalent.</p>
<p dir="auto">if I create class property and assign in a bound function, in the generated code I can access particular arguments without problem, but if I try to access <code class="notranslate">arguments</code> it brings class constructor's <code class="notranslate">arguments</code> into the closure and they become <code class="notranslate">arguments</code> of the bound function.</p>
<p dir="auto">this is what I'm trying to achieve</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="class Foo extends Component {

  componentDidMount() {
    $(document).on('click', this.onEvent);
  }

  onEvent = (event) =&gt; {
    console.log(event);
    console.log(arguments);
  };
}"><pre class="notranslate"><code class="notranslate">class Foo extends Component {

  componentDidMount() {
    $(document).on('click', this.onEvent);
  }

  onEvent = (event) =&gt; {
    console.log(event);
    console.log(arguments);
  };
}
</code></pre></div>
<p dir="auto">in <code class="notranslate">onEvent</code> the <code class="notranslate">event</code> argument will be a jquery event like expected. but <code class="notranslate">arguments</code> will not be method arguments but constructor arguments instead.</p>
<p dir="auto">this <a href="https://babeljs.io/repl/#?experimental=true&amp;evaluate=true&amp;loose=false&amp;spec=false&amp;code=class%20Foo%20%7B%0A%20%20%0A%20%20componentDidMount%28%29%20%7B%0A%20%20%20%20%24%28document%29.on%28'click'%2C%20this.onEvent%29%3B%0A%20%20%7D%0A%20%20%0A%20%20onEvent%20%3D%20%28event%29%20%3D%3E%20%7B%0A%20%20%20%20console.log%28event%29%3B%0A%20%20%20%20console.log%28arguments%29%3B%0A%20%20%7D%3B%0A%7D" rel="nofollow">REPL</a> shows what code gets generated.</p>
<p dir="auto">now, I may not know ES6 well enough to understand why is this happening. but I couldn't find any mention of such a "feature", so this might be a bug.</p>