0

What is the difference between creating an instance of object with new keyword and extending a class in JS?

First example with new keyword;

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


const dog = new Animal("Golden")
dog.bark = function(){console.log("bark")}

dog.bark()

Second example with extending:

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

class Dog extends Animal {
  bark() {
    console.log('Woof!');
  }
}

const myDog = new Dog('Fido');
console.log(myDog.name); // expected output: "Fido"
myDog.bark(); // expected output: "Woof!"

Are these two doing the same thing? Which one should I use?

tadman
  • 208,517
  • 23
  • 234
  • 262
Cagatay
  • 37
  • 1
  • 7
  • 1
    Try getting a different dog to bark when creating a new `Animal`. – Heretic Monkey May 01 '23 at 19:26
  • You're creating an instance with new in both examples... – jonrsharpe May 01 '23 at 19:26
  • 1
    I suggest understanding [what the `new` keyword does](https://stackoverflow.com/q/1646698/215552), then perhaps this will make more sense. – Heretic Monkey May 01 '23 at 19:32
  • I can created different dog and add bark method again. The problem is I should add again which means duplication of codes. – Cagatay May 01 '23 at 19:33
  • Please don't respond to comments with code; Instead [edit] your question to make it clearer. The code shows, however, why you'd want to use a subclass; You've written the `bark` function twice. – Heretic Monkey May 01 '23 at 19:34
  • I am trying to understand but I need a much more simplified answer like explaning to a child :)) – Cagatay May 01 '23 at 19:35
  • 1
    Sorry I have deleted it. Yes, I have to write twice which is doesn't make sense in OOP. So I can say that when I extend the class and add method to it, I can create many instances from extended class. So It is much better for OOP. – Cagatay May 01 '23 at 19:36
  • `const dog1 = new Animal("Golden"); const dog2 = new Animal("mutt");` so you want to add bark to each one? No? then you got your answer why it is not a great practice. – epascarello May 01 '23 at 19:42
  • No, they don't do the same thing. The first means a specific `Animal` can bark, the second means all `Dog`'s can bark. What you **"should"** do depends on what you **need** to do--it's unlikely you **need** instance-specific `bark` methods if you want to generalize `Dog`s. The second also means you **know** `Dog`'s can bark, the first means you have to check if an `Animal` can bark. – Dave Newton May 01 '23 at 19:43

5 Answers5

2

Use depends on your needs; if you want to add unique behavior to a single instance, you can use the first approach. If you want to create a new class with additional functionality, you can extend an existing class using the second approach.

oluroyleseyler
  • 802
  • 2
  • 5
2

When extending a class, you can very easily construct many new instances using your new behavior. When directly adding values to a constructed instance, that behavior is not shared and only exists for that one instance. The most common approach would be to extend the class, unless your subclass is only going to be used in one place, where this practice is still uncommon to see.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0xLogN
  • 3,289
  • 1
  • 14
  • 35
1

There's a reason for using inheritance and it's often to do with avoiding injection of individual functions like you do with dog.bark. There are cases where individual customization is the best option, but for an entire "class" of objects with similar properties, this is not usually the best call.

A class communicates a lot more about what it is, and importantly, how it can and should be used. If you have a Dog here then you know how it works, there's no ambiguity. If you use the injection model, you will need to probe for individual methods and even then there's no certainty as to if they'll work as expected.

This is especially relevant with strong typing as you might get with TypeScript.

tadman
  • 208,517
  • 23
  • 234
  • 262
1

In OOP, classes describe objects (instances) by their common behaviour and properties. Extending a class means defining a subclass: Providing a more specific type of class than the superclass.

JavaScript allows you to dynamically set new properties on objects. Using this to effectively implement a subclass without actually defining a subclass results in ambiguity:

(Without duck-typing) you will be unable to differentiate between objects of that abnormal "subclass" and those not of that "subclass" (but its "superclass").

In other words: Implementing on the objects individually results in the properties to not be shared, since they don't exist on a class (read: prototype).

Consider using a proper subclass if you require more than one such object or have to differentiate between them by (proto)types. Personally, I'd recommend using subclasses when the object already has a class.

Oskar Grosser
  • 2,804
  • 1
  • 7
  • 18
0

I think the final answer should be like this:

Classes and objects are not the same thing. Classes are template to create one or many objects.

In the first example, I am creating an Dog object from Animal class and I cannot create more objects from object. So it is only for one time purpose.

In the second example, I am creating new class (subclass) by extending a class which means I can create many new objects from Dog class.

So, what is important is to understand what you really need.

( Please correct me If I am wrong :) )

Cagatay
  • 37
  • 1
  • 7