JavaScript Dualistic Type System VS Python Unified Object System. Brief overview

Now let's get to the topic!

Content

What approaches are there?

I think it's worth starting with the fact that there are different approaches to “Object Architecture” in different programming languages:

And today I want to take a closer look at how the type and object systems are implemented in Python and JavaScript.

Object Architecture in JavaScript

In JavaScript, the main types are divided into two categories: primitives (more on them later) and objects. Let's take a closer look at what this object.

An object in programming languages ​​is a data structure that is described by internal properties and methods.

This is the definition I came up with, let’s figure it out.

By internal properties I mean fields (attributes). Here is an example of object creation code that fits our definition perfectly:

let person = {
  name: "Alex",
  age: 33
}

We have an object person and its attributes name And age with the values ​​”Alex” and 33.

There was also something about methods… exactly! In addition to attributes, our object can have methods (in other words, a function bound to this object). The sample code would look something like this:

let person = {
  name: "Alex",
  age: 33,
  
  sayHello: function() {
    alert('Hello!')
  }
}

Now we can call our new method this way:

person.sayHello() // Выведет "Hello!"

Now we have our full-fledged object! Overall, the definition is out of the way, let's look at the architecture…

Primitives and objects

There are 8 main types in JS:

All types except ours object are primitives. We won’t go into detail about all of them, we’ll just say what distinguishes them. from the object. And the key difference is that primitives do not have their own properties and methods.

let name = "Alex";  // Строка как она есть

Someone will say: “But we can call methods on primitives…”. Yes, we can, but this is all thanks to the fact that JavaScript carefully wraps primitives when we want to call a particular method. For example, we want to display our name in upper case, then we will do this:

let name="Alex"
alert(name.toUpperCase()) // Под капотом JS делает так: 
                          // alert(String(name).toUpperCase())

A view from the OOP side

Having quickly run through the primitives, we move on – OOP and classes. And here we can introduce a second definition for the object.

An object is an instance of a class containing properties and methods.

In JS, support for OOP and classes was introduced only recently (2015, when the language itself was created in 1995). Initially, the language was conceived as procedural, with support prototyping programming (more on that later).
Let me just add that JavaScript has a strong functional paradigmso it's useful to mention it as an alternative to the object-oriented style.

Classes are literally templates for objects (instances). And classes are exactly what (on the Python side) will be contrasted with prototyping later in the article.

Examples and differences in code:

Hidden text
class Person {        // Объявление класса
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const person = new Person('Alice', 30);  // Создание объекта
const person = {    // Классический объект
  name: 'Alice',
  age: 30,
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

Prototyping and JavaScript

Prototyping is a powerful tool in the right hands. It is thanks to this concept (in my opinion) that JS was without classes for so long and coped with its tasks perfectly. So what is it about?

Prototyping is a mechanism by which some objects can inherit properties and methods from others.

Here it would probably be necessary to say about what it is inheritancebut I think in general it will be clear from the context. (I'll hope so)

Every object in JavaScript has a hidden property [[Prototype]]which points to another object – prototype. If an object needs access to a property or method that it does not itself have, JavaScript tries to find that property or method in its prototype. If the property is not found, the search continues along the prototype chain until the property is found or the chain ends (which eventually leads to Object.prototype). It's hard, we'll figure it out.

Let me give you a classic example: Let's create an object animal and object dogfor which the object animal will be a prototype (in other words: dog inherited from animal).

const animal = {
  eats: true,
  walk() {
    console.log("Animal walks");
  }
};

const dog = {
  bark() {
    console.log("Dog barks");
  }
};

Object.setPrototypeOf(dog, animal) // Устанавливаем для dog прототип animal
dog.bark();  // Dog barks
dog.walk();  // Animal walks (наследовано от прототипа)

I advise you to read more about prototypes on other resources, here I’ll just note that prototyping can compete with OOP in other languages ​​and by the way about them…

Object Architecture in Python

Now let's talk about a language in which a direct alternative to prototyping is Object-oriented approach.

Here it is definitely worth saying a phrase that every programmer who has at least once encountered this language should know: “Everything in Python is an object”. ‎ More specifically, objects are really any entity: strings, numbers, lists, dictionaries, classes, functions, etc. Moreover, any operations under the hood are methods of these objects. Example:

5 + 10  # Это эквивалентно вызову 5.__add__(10)

In the example we see the magic method __add__which provides the addition operation. There is no need to go into details, the main thing is to understand what I stated above: any operations under the hood are methods of objects.

The most attentive ones have already noticed that we were talking specifically about a method, which in turn should relate directly to any class. Here it should be noted that all object architecture Python is built around OOP.

All built-in data types in the language are classes. (This is what makes the example above possible)

print(type(41)) # Вывод: <class 'int'>

Since in the last part we talked about inheritancethanks to prototyping, then let's look at it in OOP:

class Animal:
    def __init__(self):
        self.eats = True

    def walk(self):
        print("Animal walks")

class Dog(Animal):  # Так наследуются классы в Python
    def bark(self):
        print("Dog barks")

dog = Dog() # Создание экземлпяра объекта
dog.bark()  # Dog barks
dog.walk()  # Animal walks (наследовано от Animal)

Of course, classes and prototypes differ primarily in syntax (since they are completely different mechanisms), but the main difference: this copies.

Again, everything in Python is an object, so there is no separate type for objects like there is in JS.

What's better?

Of course, it’s impossible to say unequivocally, because these are different approaches to objects as a whole.
On the one hand, I like objects in JS (even purely visually), on the other hand, when choosing prototyping or OOP, I will be entirely in favor of OOP. Let me remind you that prototyping and objects in JS are more about “building blocks in our program”, when classes, in turn, are “templates” (accordingly, their instances are these “building blocks”)
I think that each developer has the right to choose from the two approaches according to his own preferences.

It is important to note that the basic concepts of object-oriented programming can be implemented through prototyping (we are talking about inheritance, encapsulation And polymorphism (whoever hears these words for the first time – I advise you to read it, it will definitely come in handy)).
However, when trying to apply this in practice, I encountered greater difficulties than in OOP.


My little comparison has come to an end, I thank everyone who has read up to this point and I hope that this material was useful (or at least interesting) for you.
I will gladly accept feedback in the comments!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *