codestory

Die Anleitung zu TypeScript Closures

  1. Was ist Closure?
  2. Die Pfeilsyntax
  3. Definieren Sie einen Funktionstyp
  4. Funktionstyp im Parameter

1. Was ist Closure?

In der Programmiersprache TypeScript ist Closure eine spezielle Funktion.
  • Ähnlich wie eine Funktion ist eine Closure ein Block von Anweisungen mit Parametern und kann einen Wert oder nichts zurückgeben
  • Im Gegensatz zu einer Funktion hat eine Closure keinen Namen. Sie können es jedoch durch eine Variable identifizieren.
Die Syntax:
// Closure syntax
function(arg1: data_type1, arg2: data_type2, argN: data_typeN) {
   // Statements
}
// Declare a variable as an alias for Closure
var alias = function(arg1: data_type1, arg2: data_type2, argN: data_typeN) {
   // Statements
};
Das folgende Beispiel zeigt den Unterschied zwischen einer Funktion und einer Closure. Zum Schluss: Eine Closure ist eine Funktion ohne Namen.
// This is a function called sayHello
function sayHello(name: string) {
    console.log(`Hello ${name}`);
}
// This is a closure (A function without name)
function (name: string) {
    console.log(`Hello ${name}`);
}
Grundsätzlich Wenn Sie eine Closure erstellen, die Sie nicht sofort verwenden, müssen Sie sie identifizieren, sonst meldet der Compiler einen Fehler. Zum Beispiel:
Closure ID Example
// Compile Error!!!!!
function(a: number, b: number) {
    return a + b;
}
// OK
var closureId = function(a: number, b: number) {
    return a + b;
}
Möglicherweise brauchen Sie für eine Closure nicht identifizieren, wenn Sie sie erstellen und direkt aufrufen.
closure_ex1.ts
// Create a Closure and call it directly!
(function (name: string) {
    console.log(`Hello ${name}`);
})('Tom');

// --- Equivalent to: ---

// Identifier for a closure:
var sayHello = function (name: string) {
    console.log(`Hello ${name}`);
};
// Call closure via identifier:
sayHello('Tom');
Ein anderes Beispiel:
closure_ex2.ts
// Create a Closure and call it directly!
var result1 = (function (a: number, b: number) {
    return a + b;
})(100, 200);

// --- Equivalent to: ---

// Identifier for a closure:
var sum = function (a: number, b: number) {
    return a + b;
};
// Call closure via identifier:
var result2 = sum(100, 200);

2. Die Pfeilsyntax

Mit TypeScript können Sie eine Closure mithilfe der Pfeilsyntax deklarieren, die auch allgemein als Syntax Lambda bekannt ist. Im Vergleich zur traditionellen Syntax lässt die Pfeilsyntax das Schlüsselwort function weg und fügt einen Pfeil ( => ) zwischen dem Parameterblock und dem Inhaltsblock hinzu.
// Arrow Syntax (Lambda Syntax):
(arg1: data_type1, arg2: data_type2, argN: data_typeN) => {
    // Statements
}

// Traditional Syntax:
function(arg1: data_type1, arg2: data_type2, argN: data_typeN)  {
    // Statements
}
Zum Beispiel:
closure_arrow_ex1.ts
// Create a Closure with Arrow Syntax.
var introduction = (name: string, country?: string) => {
    if (country) {
        console.log(`Hello, My name is ${name} from ${country}`);
    } else {
        console.log(`Hello, My name is ${name}`);
    }
};
// Call the Closure
introduction('Tom', 'USA');

// --- Equivalent to: ----

// Create a Closure with Arrow Syntax and call it directly:
((name: string, country?: string) => {
    if (country) {
        console.log(`Hello, My name is ${name} from ${country}`);
    } else {
        console.log(`Hello, My name is ${name}`);
    }
})('Tom', 'USA');
Wenn der Inhalt des Closures nur aus einem Ausdruck besteht, können Sie ihn kürzer schreiben:
var closureId1 =  (arg1: data_type1, arg2: data_type2, argN: data_typeN)  => {
    console.log('Something');
}
// --- Equivalent to: ----
var closureId1 =  (data_type1 arg1, data_type2 arg2, data_typeN argN) => console.log('Something');

var closureId2 =  function(arg1: data_type1, arg2: data_type2, argN: data_typeN) => {
    return a_value;
}
// --- Equivalent to: ----
var closureId2 =  function(arg1: data_type1, arg2: data_type2, argN: data_typeN) => a_value;
Zum Beispiel:
closure_arrow_ex2.ts
// Create a Closure
var minus = (a: number, b: number) => a - b;

var result = minus(100, 200); // Call a closure.
console.log(`result = ${result}`);

// Create a Closure
var sayBye = (name: string) => console.log(`Bye ${name}`);
sayBye('Tom'); // Call a closure.
Output:
result = -100
Bye Tom

3. Definieren Sie einen Funktionstyp

In TypeScript wird das Schlüsselwort type verwendet, um einen neuen Datentyp zu definieren. In diesem Abschnitt besprechen wir, wie das Schlüsselwort type verwendet wird, um einen Funktionstyp (auch Closure-Typ genannt) zu definieren.
Die Syntax:
type Function_Type_Name = (arg1: data_type1, arg2: data_type2, argN: data_typeN) => return_type;
Beispiel: Definieren Sie einen Funktionstyp, der einen Parameter vom Typ number akzeptiert und einen Wert vom Typ number zurückgibt:
function_type_ex1.ts
// A Function Type:
type TaxCalculator = (amount: number) => number;
 
function function_type_ex1_test()  {
    var usTaxCalculator: TaxCalculator = (amount: number) =>  {
        return amount * 10 / 100;
    };
    var vnTaxCalculator: TaxCalculator = (amount: number) =>  amount * 5 / 100;

    var caTaxCalculator: TaxCalculator = function(amount: number)  {
        return amount * 8 / 100;
    }
    const AMOUNT = 1000;
    var usTaxAmount = usTaxCalculator(AMOUNT);
    var vnTaxAmount = vnTaxCalculator(AMOUNT);
    var caTaxAmount = caTaxCalculator(AMOUNT);

    console.log(`Tax amount according to US calculation: ${usTaxAmount}`);
    console.log(`Tax amount according to Vietnam calculation: ${vnTaxAmount}`);
    console.log(`Tax amount according to Canada calculation: ${caTaxAmount}`);
}
function_type_ex1_test(); // Call the function.
Output:
Tax amount according to US calculation: 100
Tax amount according to Vietnam calculation: 50
Tax amount according to Canada calculation: 80

4. Funktionstyp im Parameter

Function Type kann als Parameter einer anderen Funktion, Closure, Methode oder eines Konstruktors auftreten.
function_type_in_args_ex1.ts
// Define a Function Type:
type MyTaxCalculator = (value: number) => number;

function calculateTaxAmount1(amount: number, calculator: MyTaxCalculator) {
    var taxAmount = calculator(amount);
    console.log(`Tax Amount: ${taxAmount}`);
}
// --- Equivalent to: ---

function calculateTaxAmount2(amount: number, calculator: (value: number) => number) {
    var taxAmount = calculator(amount);
    console.log(`Tax Amount: ${taxAmount}`);
}
Zum Beispiel:
function_type_in_args_ex2.ts
// A Function accepts 2 parameters:
// 1 - amount: number
// 2 - calculator : (number) => (number)
function printTaxAmount(amount: number, calculator: (value: number) => number) {
    var taxAmount = calculator(amount);
    console.log(`Tax Amount: ${taxAmount}`);
}
function function_type_in_args_ex2_test() {
    // Function Type: (number) => (number)
    var usTaxCalculator = (value: number) => {
        return value * 10 / 100;
    };
    // Function Type: (number) => (number)
    var vnTaxCalculator: TaxCalculator = (value: number) => value * 5 / 100;

    printTaxAmount(1000, usTaxCalculator);
    printTaxAmount(1000, vnTaxCalculator);
    printTaxAmount(1000, (value: number) => value * 8 / 100);
}
function_type_in_args_ex2_test(); // Call the function.
Output:
Tax Amount: 100
Tax Amount: 50
Tax Amount: 80