We used to not add an internal const binding to the internal class environment for the name of the ClassDeclaration. That was so we would match FunctionDeclaration.
In the latest spec this has changed and now we always have a const binding. This is a change in behavior and we had consensus on the old behavior.
class C {
m() {
return C;
}
}
var C2 = C;
C = 42;
assert.equal(new C().m(), 42);
I'm not opposed to this new behavior but it is not what we agreed upon.
It's pretty clear that the binding behavior of function declarations (and how it differs from FunctinonExpression) is a legacy design bug that we would do over if we weren't afraid of breakage.
The argument for preserving that behavior in class declarations was for consistency with function declarations. But we seem to have abandoned the goal of class declaration/function declaration consistency in a number of other ways.
Finally, there are many reasons (not just recursion) that various parts of a class body might need to reliably reference its actual class by name(and fixes for functions, such as function.callee wouldn't cover all those use cases).
So, I'm planning on leaving the binding as current specified and expect the world to be a better place because of it.