8.7 Code Generation

When the output target is ECMAScript 2015 or higher, type parameters, implements clauses, accessibility modifiers, and member variable declarations are removed in the emitted code, but otherwise class declarations are emitted as written. When the output target is ECMAScript 3 or 5, more comprehensive rewrites are performed, as described in this section.

8.7.1 Classes Without Extends Clauses

A class with no extends clause generates JavaScript equivalent to the following:

  1. var <ClassName> = (function () {
  2. function <ClassName>(<ConstructorParameters>) {
  3. <DefaultValueAssignments>
  4. <ParameterPropertyAssignments>
  5. <MemberVariableAssignments>
  6. <ConstructorStatements>
  7. }
  8. <MemberFunctionStatements>
  9. <StaticVariableAssignments>
  10. return <ClassName>;
  11. })();

ClassName is the name of the class.

ConstructorParameters is a comma separated list of the constructor’s parameter names.

DefaultValueAssignments is a sequence of default property value assignments corresponding to those generated for a regular function declaration, as described in section 6.6.

ParameterPropertyAssignments is a sequence of assignments, one for each parameter property declaration in the constructor, in order they are declared, of the form

  1. this.<ParameterName> = <ParameterName>;

where ParameterName is the name of a parameter property.

MemberVariableAssignments is a sequence of assignments, one for each instance member variable declaration with an initializer, in the order they are declared, of the form

  1. this.<MemberName> = <InitializerExpression>;

where MemberName is the name of the member variable and InitializerExpression is the code generated for the initializer expression.

ConstructorStatements is the code generated for the statements specified in the constructor body.

MemberFunctionStatements is a sequence of statements, one for each member function declaration or member accessor declaration, in the order they are declared.

An instance member function declaration generates a statement of the form

  1. <ClassName>.prototype.<MemberName> = function (<FunctionParameters>) {
  2. <DefaultValueAssignments>
  3. <FunctionStatements>
  4. }

and static member function declaration generates a statement of the form

  1. <ClassName>.<MemberName> = function (<FunctionParameters>) {
  2. <DefaultValueAssignments>
  3. <FunctionStatements>
  4. }

where MemberName is the name of the member function, and FunctionParameters, DefaultValueAssignments, and FunctionStatements correspond to those generated for a regular function declaration, as described in section 6.6.

A get or set instance member accessor declaration, or a pair of get and set instance member accessor declarations with the same name, generates a statement of the form

  1. Object.defineProperty(<ClassName>.prototype, "<MemberName>", {
  2. get: function () {
  3. <GetAccessorStatements>
  4. },
  5. set: function (<ParameterName>) {
  6. <SetAccessorStatements>
  7. },
  8. enumerable: true,
  9. configurable: true
  10. };

and a get or set static member accessor declaration, or a pair of get and set static member accessor declarations with the same name, generates a statement of the form

  1. Object.defineProperty(<ClassName>, "<MemberName>", {
  2. get: function () {
  3. <GetAccessorStatements>
  4. },
  5. set: function (<ParameterName>) {
  6. <SetAccessorStatements>
  7. },
  8. enumerable: true,
  9. configurable: true
  10. };

where MemberName is the name of the member accessor, GetAccessorStatements is the code generated for the statements in the get acessor’s function body, ParameterName is the name of the set accessor parameter, and SetAccessorStatements is the code generated for the statements in the set accessor’s function body. The ‘get’ property is included only if a get accessor is declared and the ‘set’ property is included only if a set accessor is declared.

StaticVariableAssignments is a sequence of statements, one for each static member variable declaration with an initializer, in the order they are declared, of the form

  1. <ClassName>.<MemberName> = <InitializerExpression>;

where MemberName is the name of the static variable, and InitializerExpression is the code generated for the initializer expression.

8.7.2 Classes With Extends Clauses

A class with an extends clause generates JavaScript equivalent to the following:

  1. var <ClassName> = (function (_super) {
  2. __extends(<ClassName>, _super);
  3. function <ClassName>(<ConstructorParameters>) {
  4. <DefaultValueAssignments>
  5. <SuperCallStatement>
  6. <ParameterPropertyAssignments>
  7. <MemberVariableAssignments>
  8. <ConstructorStatements>
  9. }
  10. <MemberFunctionStatements>
  11. <StaticVariableAssignments>
  12. return <ClassName>;
  13. })(<BaseClassName>);

In addition, the ‘__extends’ function below is emitted at the beginning of the JavaScript source file. It copies all properties from the base constructor function object to the derived constructor function object (in order to inherit static members), and appropriately establishes the ‘prototype’ property of the derived constructor function object.

  1. var __extends = this.__extends || function(d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function f() { this.constructor = d; }
  4. f.prototype = b.prototype;
  5. d.prototype = new f();
  6. }

BaseClassName is the class name specified in the extends clause.

If the class has no explicitly declared constructor, the SuperCallStatement takes the form

  1. _super.apply(this, arguments);

Otherwise the SuperCallStatement is present if the constructor function is required to start with a super call, as discussed in section 8.3.2, and takes the form

  1. _super.call(this, <SuperCallArguments>)

where SuperCallArguments is the argument list specified in the super call. Note that this call precedes the code generated for parameter properties and member variables with initializers. Super calls elsewhere in the constructor generate similar code, but the code generated for such calls will be part of the ConstructorStatements section.

A super property access in the constructor, an instance member function, or an instance member accessor generates JavaScript equivalent to

  1. _super.prototype.<PropertyName>

where PropertyName is the name of the referenced base class property. When the super property access appears in a function call, the generated JavaScript is equivalent to

  1. _super.prototype.<PropertyName>.call(this, <Arguments>)

where Arguments is the code generated for the argument list specified in the function call.

A super property access in a static member function or a static member accessor generates JavaScript equivalent to

  1. _super.<PropertyName>

where PropertyName is the name of the referenced base class property. When the super property access appears in a function call, the generated JavaScript is equivalent to

  1. _super.<PropertyName>.call(this, <Arguments>)

where Arguments is the code generated for the argument list specified in the function call.