Issue 1:
Input Code

The following test suite describes the issue:

import {expect} from 'chai';

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

describe('async bound handlers', function() {
lazy('demo', () => 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);
});
});
});

Babel Configuration (.bablerc, package.json, cli command)

Using broccoli-babel-transpiler with the following options:

{
nonStandard: true,
moduleIds: false,
modules: 'system',
externalHelpers: true,
stage: 0,
// …other project-specific configuration (extensions, directories, etc)
}

Expected Behavior

When defining a bound async function within an ES6 class, like so:

class Demo {
hello = async (name) => `Hello, ${name}!`;
}

I would expect name to be defined.

Current Behavior

With the above example given for expected behavior, the value of name is bound to the first argument given to the constructor for Demo.

Possible Solution

A workaround is to declare the bound function without the async keyword, and have it return a self-evaluating function with the async keyword containing the original logic. For example:

class Demo {
hello = (name) => (async () => `Hello, ${name}!`)();
}

A possible solution might be for Babel to do this automatically.

Context

In practice, our React project passes bound functions as callbacks (e.g: onClick). Rather than dynamically binding these using :: or Function#bind, which create new objects that violate shallow prop comparisons and trigger needless re-rendering (see Performance Engineering with React), we bind these using the pattern discussed here.

A fair number of our handler functions have asynchronous behavior, and we'd like to take advantage of the async keyword as we have with our unbound class functions. The obvious way to do this is to declare the assigned function to have the async keyword, which triggers the errant behavior.

In short, we want the job variable in both functions declared below to be consistent:

class Demo {
async performAsync(job) {/*…process the given job…*/}
boundPerformAsync = async (job) => {/*…process the given job…*/}
}

this.performAsync(job) and this.boundPerformAsync(job) should be functionally equivalent.

Issue 2:
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 arguments it brings class constructor's arguments into the closure and they become arguments of the bound function.

this is what I'm trying to achieve

class Foo extends Component {

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

onEvent = (event) => {
console.log(event);
console.log(arguments);
};
}

in onEvent the event argument will be a jquery event like expected. but arguments will not be method arguments but constructor arguments instead.

this REPL shows what code gets generated.

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.