Skip to content

Latest commit

 

History

History
280 lines (197 loc) · 8.68 KB

Purpose-of-new-keyword.md

File metadata and controls

280 lines (197 loc) · 8.68 KB

What is the Purpose of the new Keyword in JavaScript ?

The new keyword in JavaScript is a fundamental tool used to create instances of objects that have a specific prototype. It plays a crucial role in object-oriented programming within JavaScript by enabling the creation of multiple objects based on constructor functions or classes. Understanding how new works is essential for effective JavaScript programming, especially when dealing with object creation and inheritance.


1. Understanding the new Keyword

When you use the new keyword, it performs several operations under the hood to create a new object. Here's a step-by-step breakdown of what happens:

  1. Creates a New Object: A new empty object is created.
  2. Sets the Prototype: The new object's internal [[Prototype]] property is set to the constructor function's prototype property.
  3. Binds this: The constructor function is called with this bound to the new object.
  4. Returns the Object: If the constructor doesn't explicitly return an object, the newly created object is returned by default.

2. Syntax of the new Keyword

const instance = new ConstructorFunction(arguments);
  • ConstructorFunction: A function intended to create and initialize objects.
  • arguments: Parameters passed to the constructor function to initialize the object properties.

3. Creating Objects with Constructor Functions

Before the introduction of ES6 classes, constructor functions were the primary way to create multiple similar objects.

Example: Using a Constructor Function

// Constructor function
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function () {
    console.log(`Hello, my name is ${this.name}.`);
  };
}

// Creating instances
const alice = new Person("Alice", 30);
const bob = new Person("Bob", 25);

alice.greet(); // Output: Hello, my name is Alice.
bob.greet(); // Output: Hello, my name is Bob.

Key Points:

  • The new keyword creates a new instance of Person.
  • Each instance has its own name, age, and greet method.

4. Using ES6 Classes with the new Keyword

ES6 introduced the class syntax, which provides a more straightforward and cleaner way to create constructor functions and handle inheritance.

Example: Using a Class

// Class definition
class Animal {
  constructor(name, species) {
    this.name = name;
    this.species = species;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

// Creating instances
const lion = new Animal("Leo", "Lion");
const tiger = new Animal("Tiggy", "Tiger");

lion.speak(); // Output: Leo makes a noise.
tiger.speak(); // Output: Tiggy makes a noise.

Key Points:

  • The constructor method initializes the object properties.
  • Methods defined within the class are added to the prototype, ensuring they are shared across instances.

5. What Happens Internally When Using new

To better understand the new keyword, let's examine its internal operations by manually replicating what new does.

Manual Implementation of new

function myNew(constructor, ...args) {
  // 1. Create a new empty object
  const obj = {};

  // 2. Set the prototype
  Object.setPrototypeOf(obj, constructor.prototype);

  // 3. Bind `this` and call the constructor
  const result = constructor.apply(obj, args);

  // 4. Return the object
  return result instanceof Object ? result : obj;
}

// Constructor function
function Car(make, model) {
  this.make = make;
  this.model = model;
}

// Creating an instance using myNew
const myCar = myNew(Car, "Toyota", "Corolla");
console.log(myCar); // Output: Car { make: 'Toyota', model: 'Corolla' }

Explanation:

  • Step 1: A new empty object obj is created.
  • Step 2: The prototype of obj is set to Car.prototype.
  • Step 3: The Car constructor is called with this bound to obj, initializing its properties.
  • Step 4: The newly created object is returned.

6. Benefits of Using the new Keyword

  • Object Creation: Simplifies the creation of multiple similar objects without repetitive code.
  • Prototype Inheritance: Facilitates inheritance by linking objects to their constructor's prototype.
  • Encapsulation: Allows encapsulation of object properties and methods within constructor functions or classes.
  • Code Reusability: Promotes reusability by enabling the creation of instances that share common behavior.

7. Common Pitfalls and Best Practices

Pitfall 1: Forgetting to Use new

If you call a constructor function without new, this inside the function will refer to the global object (window in browsers), leading to unintended side effects.

function Gadget(name) {
  this.name = name;
}

const phone = Gadget("iPhone"); // Forgot to use `new`
console.log(phone); // Output: undefined
console.log(window.name); // Output: 'iPhone' (in browsers)

Solution:

  • Always use new when calling constructor functions.
  • Alternatively, use ES6 classes which throw an error if called without new.

Pitfall 2: Returning Primitive Values from Constructors

If a constructor function returns a primitive value, it is ignored, and the new object is returned instead.

function Book(title) {
  this.title = title;
  return "Not an object";
}

const myBook = new Book("JavaScript Guide");
console.log(myBook.title); // Output: 'JavaScript Guide'
console.log(myBook); // Output: Book { title: 'JavaScript Guide' }

Solution:

  • Ensure constructors return objects if you intend to override the default behavior.

8. The new Keyword vs. Factory Functions

While the new keyword and constructor functions/classes are traditional methods for object creation in JavaScript, factory functions offer an alternative approach without using new.

Example: Factory Function

function createUser(name, age) {
  return {
    name,
    age,
    greet() {
      console.log(`Hi, I'm ${name} and I'm ${age} years old.`);
    },
  };
}

const user1 = createUser("Alice", 28);
user1.greet(); // Output: Hi, I'm Alice and I'm 28 years old.

Comparison:

Feature Using new with Constructors/Classes Factory Functions
Syntax Requires new keyword No new keyword required
Prototype Linking Inherits from constructor's prototype Each object has its own methods unless explicitly linked
Inheritance Easier with extends in classes More manual, often using Object.create
Error Handling Throws errors if called without new Safer as it doesn't rely on this binding

9. Use Cases of the new Keyword

  • Creating Instances of Classes: When working with ES6 classes to instantiate objects.

    class Rectangle {
      constructor(width, height) {
        this.width = width;
        this.height = height;
      }
    
      area() {
        return this.width * this.height;
      }
    }
    
    const rect = new Rectangle(5, 10);
    console.log(rect.area()); // Output: 50
  • Constructor Functions: Before ES6 classes, constructor functions were commonly used to create objects.

    function Circle(radius) {
      this.radius = radius;
      this.area = function () {
        return Math.PI * this.radius ** 2;
      };
    }
    
    const circle = new Circle(3);
    console.log(circle.area()); // Output: 28.274333882308138
  • Inheritance: Leveraging prototypes for inheritance.

    function Vehicle(type) {
      this.type = type;
    }
    
    Vehicle.prototype.describe = function () {
      console.log(`This is a ${this.type}.`);
    };
    
    function Car(brand) {
      Vehicle.call(this, "car");
      this.brand = brand;
    }
    
    Car.prototype = Object.create(Vehicle.prototype);
    Car.prototype.constructor = Car;
    
    const myCar = new Car("Toyota");
    myCar.describe(); // Output: This is a car.
    console.log(myCar.brand); // Output: Toyota

10. Conclusion

The new keyword is a powerful feature in JavaScript that facilitates object creation, inheritance, and prototype management. By understanding its mechanics and best practices, developers can write more efficient, organized, and maintainable code. Whether using traditional constructor functions or modern ES6 classes, the new keyword remains integral to JavaScript's object-oriented programming paradigm.