Function Properties and methods

"This" Keyword

In JavaScript, the keyword this refers to the object that a function is associated with. By default, this refers to the object that the function is a method of.

However, with methods like call, apply, and bind, you can manually set what this refers to. This is known as setting the context of this.

For instance, if you have a function greet and an object person, you can use greet.call(person, 'Hello'). This calls the greet function, but inside greet, this will refer to person, not the object greet was originally associated with.

This ability to change the context of this is useful when you want a function to operate in the context of a different object than it was originally associated with.

Function Properties (name, length, prototype)

Function properties are properties that are available to all functions in JavaScript. They are used to access information about the function, such as the name of the function, the number of arguments it takes, and the prototype of the function.

  • The name property returns the name of the function.
  • The length property returns the number of arguments the function takes.
  • The prototype property returns the prototype of the function.
function myFunc(a, b) {
    return a + b;
}

console.log(myFunc.name); // myFunc
console.log(myFunc.length); // 2
console.log(myFunc.prototype);
// High-level overview of the prototype chain
{
    myFunc: { // the constructor function
        prototype: { // the prototype object
            constructor: myFunc,
            // other properties and methods inherited by instances...
        }
    },
    obj: { // an instance of myFunc
        __proto__: { // the prototype object
            constructor: myFunc,
            // other properties and methods inherited from myFunc.prototype...
        }
    }
}

Yea I know right, wrap your head around that one!

FYI, I need to preface the following diagram with "I think"

Function, prototype, and instance relationships

    graph LR
    myFunc[myFunc Function] -->|has| FunctionProperties[Function Properties]
    myFunc -->|has| FunctionMethods[Function Methods]
    myFunc -->|has| FunctionPrototype[myFunc.prototype]
    FunctionPrototype -->|has| Constructor[constructor: myFunc]
    FunctionPrototype -->|has| OtherProperties[Other properties and methods]
    obj[obj Instance] -->|has| InstanceProto[obj.__proto__]
    InstanceProto -->|points to| FunctionPrototype

Prototype chain diagram

    graph LR
        Constructor -->|has| Prototype[Prototype]
        Prototype -->|has| BasePrototype[Base Prototype]
        Constructor -->|creates| Instance
        Instance -->|links| Prototype
        BasePrototype -->|__proto__ points to| Null[null]

Function Methods

Function methods are methods that are available to all functions in JavaScript. They are used to manipulate the function, such as calling the function, binding the function to a specific context, and applying the function to an array of arguments.

Function.apply()

The apply() method calls a function with a given this value and arguments provided as an array.

Below are examples of calling greet() with apply(), and the equivalent using a class.

function greet(greeting) {
    return `${greeting} ${this.name}`;
}

const user = { name: 'John' };
console.log(greet.apply(user, ['Hello,']));
// Outputs: Hello John
class UserClass {
    constructor(name) {
        this.name = name;
    }
    greet(greeting) {
        return `${greeting}, ${this.name}`;
    }
}

const user = new UserClass('John');
console.log(user.greet('Hello,')); 
// Outputs: Hello, John

Function.call()

The call() method calls a function with a given this value and arguments provided individually.

function greet(greeting) {
    return `${greeting} ${this.name}`;
}

const user = { name: 'John' };
console.log(greet.call(user, 'Hello,'));
// Outputs: Hello, John
class UserClass {
    constructor(name) {
        this.name = name;
    }
    greet(greeting) {
        return `${greeting}, ${this.name}`;
    }
}

const user = new UserClass('John');
console.log(user.greet('Hello,')); 
// Outputs: Hello, John

What is the difference between call() and apply()?

The call() and apply() methods in JavaScript are both used to call a function with a specific this value and arguments. The difference between them lies in how they handle function arguments:

  • call() takes arguments individually: func.call(thisArg, arg1, arg2, ...)
  • apply() takes arguments as an array: func.apply(thisArg, [arg1, arg2, ...])

Function.bind()

The bind() method in JavaScript creates a new function that, when called, has its this keyword set to the provided value. The bind() method also allows you to partially apply arguments to the function, meaning you can fill in some arguments and leave the rest to be filled in later when the bound function is called.

function introduce(greeting, punctuation) {
    return `${greeting}, my name is ${this.name} and I am ${this.age} ${punctuation}`;
}

const user = { name: 'John', age: 30 };

const introduceUser = introduce.bind(user, 'Hello');
console.log(introduceUser('!')); 
// Outputs: Hello, my name is John and I am 30!

This is the equivalent using a class:

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
        this.introduce = (greeting, punctuation) => {
            return `${greeting}, my name is ${this.name} and I am ${this.age} ${punctuation}`;
        };
    }
}

const user = new User('John', 30);
console.log(user.introduce('Hello', '!')); 
// Outputs: Hello, my name is John and I am 30!

Additional Resources