diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8c4caa9630..7a4d808e023 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4824,7 +4824,11 @@ module ts { // Now skip arrow functions to get the "real" owner of 'this'. if (container.kind === SyntaxKind.ArrowFunction) { container = getThisContainer(container, /* includeArrowFunctions */ false); - needToCaptureLexicalThis = true; + + // When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code + if (compilerOptions.target < ScriptTarget.ES6) { + needToCaptureLexicalThis = true; + } } switch (container.kind) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6a8216f7a30..2e8502c8859 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3210,6 +3210,13 @@ module ts { emitTrailingComments(node); } + function isES6ArrowFunction(node: FunctionLikeDeclaration): boolean { + if (node.kind === SyntaxKind.ArrowFunction && compilerOptions.target >= ScriptTarget.ES6) { + return true; + } + return false; + } + function emitFunctionDeclaration(node: FunctionLikeDeclaration) { if (nodeIsMissing(node.body)) { return emitPinnedOrTripleSlashComments(node); @@ -3220,11 +3227,9 @@ module ts { emitLeadingComments(node); } - if (node.kind !== SyntaxKind.ArrowFunction) { - write("function "); - } - else if (node.kind === SyntaxKind.ArrowFunction && compilerOptions.target < ScriptTarget.ES6) { - // When targeting ES6, emit arrow function natively in ES6 by omitting function keyword and using fat arrow instead + // For targeting below es6, emit functions-like declaration including arrow function using function keyword. + // When targeting ES6, emit arrow function natively in ES6 by omitting function keyword and using fat arrow instead + if (!isES6ArrowFunction(node)) { write("function "); } @@ -3268,7 +3273,7 @@ module ts { emitSignatureParameters(node); // When targeting ES6, emit arrow function natively in ES6 - if (node.kind === SyntaxKind.ArrowFunction && compilerOptions.target >= ScriptTarget.ES6) { + if (isES6ArrowFunction(node)) { write(" => "); } @@ -3283,7 +3288,12 @@ module ts { startIndex = emitDirectivePrologues((node.body).statements, /*startWithNewLine*/ true); } var outPos = writer.getTextPos(); - emitCaptureThisForNodeIfNecessary(node); + + // In ES6, fat arrow function lexically binds this value. Therefore, when targeting es6, we can omit capturing of "this" in the fat arrow function + if (!isES6ArrowFunction(node)) { + emitCaptureThisForNodeIfNecessary(node); + } + emitDefaultValueAssignments(node); emitRestParameter(node); if (node.body.kind !== SyntaxKind.Block && outPos === writer.getTextPos()) {