Start learning free

LESSON 184 OF 348 · OBJECT-ORIENTED PROGRAMMING

Class Methods in TypeScript: Adding Behaviour

Lesson Read the full explanation

TL ; DR:

  • A method is a function that lives inside a class. Inside the method, this refers to the object it was called on.


  • Define methods inside the class body — no function keyword needed:

    class Dog {
        constructor(name) {
            this.name = name;
        }
    
        bark() {
            console.log("Woof! I am " + this.name);
        }
    }
    

  • Call it on an object with the dot operator: dog.bark();



Full lesson:

So far you've added data to a class with properties set in the constructor. The other half of OOP is behavior — actions an object can perform. That's what methods are for.


Defining a method

Inside a class body, you write methods without the function keyword:

bark() {
    console.log("Woof! I am " + this.name);
}

Use this.name to read the property of the current object.


Your task

Add a bark method that logs "Woof! I am " followed by this.name.

Woof! I am Rex
STEP 1 OF 2
    Ctrl + Enter to check

    TYPESCRIPT · OBJECT-ORIENTED PROGRAMMING

    Class Methods in TypeScript, explained

    What a method is

    Fields hold an object's data. Methods describe what the object can do. A method is a function that lives inside a class, and it runs on one particular object. Inside it, the keyword this refers to the object the method was called on, so the method can read and change that object's fields.

    Defining a method

    Write the method in the class body, with a name, parentheses for parameters, an optional return type and a block of code. There is no function keyword:

    class Dog {
        name: string;
        constructor(name: string) {
            this.name = name;
        }
    
        bark(): void {
            console.log("Woof! I am " + this.name);
        }
    }
    

    The return type void says that bark hands nothing back to its caller. It prints a message instead. A method that gives back a value declares that type instead, such as describe(): string with a return statement.

    The order of members inside the class body does not matter to the compiler. A method can use another method that is written further down, since the code only runs after the whole class has been defined. By convention, fields come first, then the constructor, then the methods.

    Calling a method

    Call a method on an object with the dot operator and parentheses:

    let rex: Dog = new Dog("Rex");
    rex.bark();
    
    Woof! I am Rex
    

    While bark runs, this is rex, so this.name is "Rex". Call the same method on another dog and this is that dog:

    let luna: Dog = new Dog("Luna");
    luna.bark();
    
    Woof! I am Luna
    

    The method is written once in the class and shared by all dogs. Only the data differs from object to object. A method can also change the object. Here rename assigns to a field, and the new name shows up the next time any method reads it:

    class Dog {
        name: string;
        constructor(name: string) { this.name = name; }
        rename(newName: string): void {
            this.name = newName;
        }
    }
    

    Parameters and return values

    Methods can take parameters and return values like any function. A method can also call another method of the same object through this:

    class Dog {
        name: string;
        constructor(name: string) { this.name = name; }
        bark(times: number): string {
            let sound = "";
            for (let i = 0; i < times; i++) sound += "Woof! ";
            return sound + "I am " + this.name;
        }
        introduce(): void {
            console.log(this.bark(2));
        }
    }
    const rex = new Dog("Rex");
    console.log(rex.bark(1));
    rex.introduce();
    
    Woof! I am Rex
    Woof! Woof! I am Rex
    

    The lesson's own bark needs neither a parameter nor a result, so it stays simpler.

    Why this is required

    Inside a method, the name of a field is not a variable. Writing just name asks the language for a variable called name, which is not what you want. You always reach the object's own data through this: this.name. The same applies to calling one method from another, as in this.bark().

    The exercise

    The starter code has a Dog class with a name field and a constructor, followed by code that creates rex and calls rex.bark(). The class has no bark yet, so the compiler reports that the property does not exist, and running the code fails with rex.bark is not a function.

    1. Add the method. Below the constructor, write bark(): void { } with an empty body. The void return type fits because the method prints and returns nothing.
    2. Fill in the body. Log "Woof! I am " followed by this.name.
    class Dog {
        name: string;
        constructor(name: string) {
            this.name = name;
        }
    
        bark(): void {
            console.log("Woof! I am " + this.name);
        }
    }
    
    let rex: Dog = new Dog("Rex");
    rex.bark();
    

    The output is:

    Woof! I am Rex
    

    Common mistakes

    • Writing function bark() in the class. Inside a class body that is a syntax error. Methods take no keyword.
    • Leaving out this.. The method then does not read the field.
    • Forgetting the parentheses on the call. rex.bark only names the method and does nothing. Add () to run it.
    • Separating methods with commas. Object literals use commas between members. Class bodies don't, and a comma between methods is a syntax error.
    • Detaching a method from its object. After const f = rex.bark;, calling f() runs the method with no object, so this is undefined and reading this.name throws Cannot read properties of undefined (reading 'name'). Always call the method through the object, as in rex.bark().
    • Expecting each object to hold its own copy. All dogs share one bark. Comparing rex.bark === luna.bark gives true.

    Key takeaways

    • A method is a function declared in the class body, with no function keyword.
    • Call it with the dot operator on an object: rex.bark().
    • Inside a method, this is the object it was called on, and fields are reached as this.name.
    • Use void as the return type when the method returns nothing.
    Keep going with TypeScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free