Category: Javascript

  • Better way of implementing public and private (#) fields in class in js

    In JavaScript, getters and setters are special methods that allow you to define how properties of an object are accessed and modified. They provide a way to control access to object properties, allowing you to add logic when getting or setting a value.

    • Getter: A getter is a method that gets the value of a specific property. It is defined using the get keyword.
    • Setter: A setter is a method that sets the value of a specific property. It is defined using the set keyword.

    Here’s how you can use getters and setters within a class:

    class Circle {
      constructor(radius) {
        this.#radius = radius; // Use # to declare a private property
      }
    
      // Getter for the radius property
      get radius() {
        return this.#radius;
      }
    
      // Setter for the radius property
      set radius(value) {
        if (value >= 0) {
          this.#radius = value;
        } else {
          console.error("Radius cannot be negative");
        }
      }
    
      get area() {
        return Math.PI * this.#radius * this.#radius;
      }
    }
    
    const myCircle = new Circle(10);
    console.log(myCircle.radius); // Output: 10 (using the getter)
    
    myCircle.radius = 15; // Output: (using the setter)
    console.log(myCircle.radius);  // 15
    
    myCircle.radius = -5;    // Error: Radius cannot be negative
    console.log(myCircle.radius);  // 15 (the value is not changed)
    
    console.log(myCircle.area); // 706.858 (calculated property)

    In this example:

    • We use #radius to store the actual radius value. The # makes it a private property, meaning it can only be accessed from within the Circle class.
    • The get radius() method returns the value of #radius.
    • The set radius(value) method checks if the provided value is valid (non-negative) before updating #radius. If the value is negative, it logs an error.
    • The get area() method calculates the area of the circle. Note that area is a read-only property, as it only has a getter and no setter.
  • Getters and Setters in JS

    In JavaScript, getters and setters are special methods that allow you to define how properties of an object are accessed and modified. They provide a way to control access to object properties, allowing you to add logic when getting or setting a value.

    • Getter: A getter is a method that gets the value of a specific property. It is defined using the get keyword.
    • Setter: A setter is a method that sets the value of a specific property. It is defined using the set keyword.

    Here’s how you can use getters and setters within a class:

    class Circle {
      constructor(radius) {
        this._radius = radius; // Use a different name for the actual property
      }
    
      // Getter for the radius property
      get radius() {
        return this._radius;
      }
    
      // Setter for the radius property
      set radius(value) {
        if (value >= 0) {
          this._radius = value;
        } else {
          console.error("Radius cannot be negative");
        }
      }
    
      get area() {
        return Math.PI * this._radius * this._radius;
      }
    }
    
    const myCircle = new Circle(10);
    console.log(myCircle.radius); // Output: 10 (using the getter)
    
    myCircle.radius = 15; // Output: (using the setter)
    console.log(myCircle.radius);  // 15
    
    myCircle.radius = -5;    // Error: Radius cannot be negative
    console.log(myCircle.radius);  // 15 (the value is not changed)
    
    console.log(myCircle.area); // 706.858 (calculated property)

    In this example:

    • We use _radius to store the actual radius value.
    • The get radius() method returns the value of _radius.
    • The set radius(value) method checks if the provided value is valid (non-negative) before updating _radius. If the value is negative, it logs an error.
    • The get area() method calculates the area of the circle. Note that area is a read-only property, as it only has a getter and no setter.

    ** The underscore in this._radius is a convention used to indicate that the _radius property is intended to be treated as a private property. Here’s why:

    Distinction from Public API: JavaScript doesn’t have true private properties like some other languages (e.g., Java). The underscore is a way for developers to signal, “Hey, this property is meant for internal use within the class. You should generally access and modify it through the provided getter and setter methods.”

    Avoiding Naming Conflicts: Using _radius avoids a naming conflict with the public radius property that is exposed through the getter and setter. If we named the internal variable radius, we’d have a naming collision.

    Encapsulation ( намек ): While not enforced by the language, this convention promotes encapsulation. Encapsulation is the idea of bundling data (properties) and methods that operate on that data within a single unit (a class), and restricting access to the internal details of the object.

    In summary, the underscore is a helpful convention in JavaScript to improve code readability and намек at intended privacy, especially in the absence of true private properties.

  • Understanding Polymorphism in JavaScript

    Understanding Polymorphism in JavaScript

    Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects of different classes to respond to the same method call in their own specific ways. JavaScript, being a dynamically typed language, implements polymorphism in a flexible manner. Here’s a breakdown of how polymorphism works in JavaScript:

    What is Polymorphism?

    The word “polymorphism” comes from Greek words meaning “many forms.” In programming, it means that one thing (like a function or a method) can take on many forms or have many different behaviors.

    Why is Polymorphism Useful?

    Polymorphism allows you to write more general and flexible code. Instead of writing separate code for each specific type of object, you can write code that works with a variety of objects.

    How is Polymorphism Achieved in JavaScript?

    Here are the primary ways polymorphism is achieved in JavaScript:

    1. Subtype Polymorphism (Inheritance and Method Overriding)

    • This is the most common way to achieve polymorphism in JavaScript. It involves two key concepts:
      • Inheritance: When you create a new class (subclass) based on an existing class (superclass), the subclass inherits the properties and methods of the superclass.
      • Method Overriding: A subclass can provide its own implementation of a method that is already defined in its superclass. This allows the subclass to customize the behavior of the method.
      Simpler Example:Let’s say we have a class called Shape with a method called draw().
    class Shape {
      draw() {
        console.log("Drawing a shape");
      }
    }

    Now, we can create subclasses of Shape for specific shapes like Circle and Square.

    class Circle extends Shape {
      draw() {
        console.log("Drawing a circle"); // Overrides the draw() method
      }
    }
    
    class Square extends Shape {
      draw() {
        console.log("Drawing a square"); // Overrides the draw() method
      }
    }

    In this example, the draw() method is polymorphic. When we call the draw() method on a Circle object, it behaves differently than when we call it on a Square object.

    const myCircle = new Circle();
    const mySquare = new Square();
    
    myCircle.draw(); // Output: "Drawing a circle"
    mySquare.draw(); // Output: "Drawing a square"
    • Even though we are calling the same method (draw()), the output is different depending on the type of object. This is polymorphism in action.

    2. Duck Typing

    • JavaScript’s dynamic nature allows for a concept called “duck typing.”
    • Instead of checking the actual type or class of an object, we check if it has the properties and methods we need.
    • The name “duck typing” comes from the saying: “If it walks like a duck and quacks like a duck, then it must be a duck.”Simpler Example:Let’s say we have a function called makeSound() that expects an object with a makeSound() method.
    function makeSound(obj) {
      if (typeof obj.makeSound === "function") {
        obj.makeSound();
      } else {
        console.log("This object can't make a sound");
      }
    }

    Now, we can pass any object to this function, as long as it has a makeSound() method.

    const dog = {
      makeSound: function() {
        console.log("Woof!");
      }
    };
    
    const cat = {
      makeSound: function() {
        console.log("Meow!");
      }
    };
    
    const myCar = {
      honk: function() {
        console.log("Honk!");
      }
    };
    
    makeSound(dog); // Output: "Woof!"
    makeSound(cat); // Output: "Meow!"
    // makeSound(myCar);  // Error: myCar doesn't have makeSound()

    In this example, the makeSound() function works with both the dog and cat objects because they both have a makeSound() method. It doesn’t care that one is a dog and the other is a cat. It would not work with myCar because it has a honk() method, not a makeSound() method.

  • Understanding the some() Array Function

    Coding partner

    Hello! I’m your Coding partner. My purpose is to help you with your coding tasks. I can assist you with writing, fixing, and understanding code. For example, if you want to write a function to sort a list of numbers, debug an error in your Python script, or understand how a specific JavaScript array method works, I can help you with that.

    You’re asking about the ES6 some() array function. Let’s break it down.

    Understanding the some() Array Function

    In simple terms, the some() function is like asking: “Does at least one item in this list meet a specific condition?”

    It goes through each item in an array and checks if that item satisfies a test you provide. If it finds even one item that passes the test, it immediately stops and returns true. If it goes through the entire array and doesn’t find any item that passes the test, it returns false.

    Simple Example

    Let’s say you have a list of fruits:

    const fruits = ['apple', 'banana', 'orange', 'grape'];

    And you want to know if at least one of the fruits has more than 5 letters in its name. You can use the some() function like this:

    const hasLongName = fruits.some(function(fruit) {
      return fruit.length > 5;
    });
    
    console.log(hasLongName); // Output: true

    Explanation of the Code:

    1. fruits.some(...): We are calling the some() function on our fruits array.
    2. function(fruit) { ... }: This is a function that will be executed for each fruit in the array. The current fruit being checked is passed as an argument to this function.
    3. return fruit.length > 5;: Inside this function, we are checking if the length of the current fruit‘s name is greater than 5. This is our test condition.
    4. hasLongName: The some() function returns true because “banana” and “orange” have more than 5 letters.

    Another Example with Numbers:

    const numbers = [1, 3, 5, 7, 9];
    
    const hasEvenNumber = numbers.some(function(number) {
      return number % 2 === 0;
    });
    
    console.log(hasEvenNumber); // Output: false

    Coding partner

    Hello! I’m your Coding partner. My purpose is to help you with your coding tasks. I can assist you with writing, fixing, and understanding code. For example, if you want to write a function to sort a list of numbers, debug an error in your Python script, or understand how a specific JavaScript array method works, I can help you with that.

    You’re asking about the ES6 some() array function. Let’s break it down.

    Understanding the some() Array Function

    In simple terms, the some() function is like asking: “Does at least one item in this list meet a specific condition?”

    It goes through each item in an array and checks if that item satisfies a test you provide. If it finds even one item that passes the test, it immediately stops and returns true. If it goes through the entire array and doesn’t find any item that passes the test, it returns false.

    Simple Example

    Let’s say you have a list of fruits:

    JavaScript

    const fruits = ['apple', 'banana', 'orange', 'grape'];
    

    And you want to know if at least one of the fruits has more than 5 letters in its name. You can use the some() function like this:

    JavaScript

    const hasLongName = fruits.some(function(fruit) {
      return fruit.length > 5;
    });
    
    console.log(hasLongName); // Output: true
    

    Explanation of the Code:

    1. fruits.some(...): We are calling the some() function on our fruits array.
    2. function(fruit) { ... }: This is a function that will be executed for each fruit in the array. The current fruit being checked is passed as an argument to this function.
    3. return fruit.length > 5;: Inside this function, we are checking if the length of the current fruit‘s name is greater than 5. This is our test condition.
    4. hasLongName: The some() function returns true because “banana” and “orange” have more than 5 letters.

    Another Example with Numbers:

    JavaScript

    const numbers = [1, 3, 5, 7, 9];
    
    const hasEvenNumber = numbers.some(function(number) {
      return number % 2 === 0;
    });
    
    console.log(hasEvenNumber); // Output: false
    

    Explanation:

    In this case, none of the numbers in the numbers array are even, so the test number % 2 === 0 (which checks if a number is divisible by 2) never returns true. Therefore, some() returns false.

    Key Takeaways:

    • some() iterates through an array.
    • It executes a provided function for each element.
    • It returns true as soon as the function returns true for any element.
    • It returns false if the function returns false for all elements.