— This article is taken from my official account “Sun Wukong, Don’t talk Nonsense”

“Objects” in JavaScript have always been less gregarious than in other languages.

When a kid with other object-oriented programming experience (C++, Java) starts writing JavaScript, he or she may be surprised:

“You say JavaScript is an object-oriented language. How is it different from other object-oriented languages I’ve been exposed to? How can it be an object-oriented language when it doesn’t even have the concept of a class (although ES6 does)?”

“Attributes can be added freely to JavaScript objects, and they can be added dynamically. The wave operation is very 6. No other object-oriented language has this functionality.”

Part of the confusion is that the concept of “object orientation” in your mind contains a default point: object orientation is class-based.

In this article, the first challenge is: What is object-oriented programming? Then take a look at what object orientation in JavaScript really is.

What is object orientation?

Let’s talk about what an object is first. Object (Object) in English, is the general name of all things, which is connected with the abstract thinking of object-oriented programming.

The Chinese word for object does not have the same universality. Therefore, in the process of learning programming, it is more as a professional term to understand.

An object in the field of computing is not a concept created out of thin air, it is an abstraction generated by the human mode of thinking. Object-oriented programming is also considered a programming paradigm that is closer to the human mindset.

So, going back to the roots, let’s look at what objects are in the human mind:

The ability to recognize physical objects is a skill learned early in life. A small brightly colored ball will attract a baby’s attention, and usually, if the ball is hidden, the child will not try to find it. When the object is out of her field of vision, in her judgment, the object does not exist. It is not until nearly one year of age that children develop so-called object concepts, which are important for future cognitive development. Showing a ball to a one-year-old and then hiding it, she usually looks for the ball, even if it’s not in sight. Through the concept of objects, the child realizes that objects have persistence and identifiers, independent of the operations imposed on them. — “Object-oriented Analysis and Design, Chapter 3”

In his book Object-oriented Analysis and Design, Grady Booch summed it up for us by arguing that, from a human cognitive perspective, objects should be one of the following:

  1. Something that can be touched or seen;
  2. Something intelligible to the human mind;
  3. Something that directs thought or action (imagining or performing an action).

With a natural definition of an object, we can describe objects in a programming language. Different designers describe objects differently in different programming languages. The most successful genre is the use of “classes” to describe objects, giving rise to popular class-based object-oriented programming languages such as C++ and Java.

The designers of JavaScript chose an unpopular approach: object-oriented prototyping. If you know a little bit about the history of JavaScript being developed, you can see why JavaScript is different: For some corporate political reasons, JavaScript was ordered by management to mimic Java when it was launched, so JavaScript founder Brendan Eich introduced language features like New and this on top of the “prototype runtime” to make it “look more like Java.”

This is why JavaScript looks different.

Because of the popularity of class-based object-oriented patterns, many JavaScript programmers before ES6 tried to make JavaScript more like class-based programming, based on prototype-based design. Many frameworks have emerged from this. But every language has its own unique design philosophy, and it’s a thankless task to force prototype-based JavaScript into class-based JavaScript.

Let’s take a look at how JavaScript designs objects.

Characteristics of JavaScript objects

In his book Object-oriented Analysis and Design, Grandy Booch summarizes several characteristics of objects:

  • Objects are uniquely identifiable: even if two objects are exactly the same, they are not the same object.
  • Stateful: Objects have states. the same object may be in different states.
  • An object has behavior: that is, the state of the object may change because of its behavior.

No matter what programming language we use, we should first understand the nature of the object. So how do JavaScript designers embody these characteristics of objects?

Let’s start with the first characteristic: objects are uniquely identifiable. Generally speaking, the unique identification of objects in various languages is reflected by memory addresses. Objects have unique identification because they have uniquely identified memory addresses. In JavaScript, any different JavaScript objects are not equal. We can simply verify that:

 var obj1 = { a : 2};
 var obj2 = { a : 2};
 
 console.log( obj1 == obj2); // false
Copy the code

Regarding the second and third characteristics of objects, “state and behavior,” different languages use different terms to describe them abstractly. In JavaScript, state and behavior are uniformly abstracted as “properties”. Considering that JavaScript designs functions as special objects, the behavior and state of objects in JavaScript can be abstracted with properties. The following is a good example of common properties and functions as objects:

 var obj1 = { 
        a : 2, 
        f() { console.log(this.a); }};Copy the code

So, to sum up, in JavaScript, the state and behavior of objects are abstracted as properties.

After realizing the basic characteristics of the object,JavaScriptThe unique feature of objects in objects is that they are highly dynamic becauseJavaScriptGives users the ability to add state and behavior to objects at run time.

The following code shows how the runtime can add attributes to an object:

var obj1 = { a : 2}; obj1.c = 21; console.log( obj1.a + obj1.c); / / 23Copy the code

If you’ve ever worked in a Java or other class-based, static programming language, this dynamic addition will come as a surprise.

Although the design approach is somewhat different, they both represent the basic characteristics of the object: identity, state, and behavior. This is just a difference in implementation, both are based on object design ideas.

The above description has already described the idea of designing JavaScript based on the basic characteristics of objects. Let’s take a look at what properties objects in JavaScript have.

Two classes of properties for JavaScript objects

To improve abstraction, JavaScript properties are designed to be more complex than other languages, providing data properties and getter/setter properties.

In JavaScript, properties are not just names and values. JavaScript uses a set of attributes to describe properties.

Let’s start with the first class of properties, data properties. It is closer to the concept of attributes in other languages. Data attributes have four characteristics.

  • Value: indicates the value of the attribute.
  • Writable: Determines whether a property can be assigned a value.
  • Enumerable: Determines if for in can enumerate this property.
  • Different: Determines whether the property can be deleted or changed.

In most cases, we only care about the value of the data attribute.

The second type of property is the getter/setter property, which also has four characteristics.

  • Getter: Function or undefined, called when fetching a property value.
  • Setter: function or undefined, called when setting property values.
  • Enumerable: Determines if for in can enumerate this property.
  • Different: Determines whether the property can be deleted or changed.

Accessor properties enable properties to execute code while reading and writing, allowing users to get completely different values when writing and reading properties.

The code that normally defines a property creates a data property. Writable, Enumerable, and different default is true. We can use the built-in function Object. GetOwnPropertyDescripter to view, as shown in the following code:

var o = { a: 1 }; o.b = 2; / / a and b are data attribute Object. GetOwnPropertyDescriptor (o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}
Copy the code

If we want to change the characteristics of a property, or define accessor properties, we can use Object.defineProperty as shown in the following example:


    var o = { a: 1 };
    Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true}); / / a and b are attribute data, but the characteristic value changes the Object. GetOwnPropertyDescriptor (o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true} o.b = 3; console.log(o.b); / / 2Copy the code

We also use the Object getOwnPropertyDescriptor to check, found that really changed the writable and enumerable features. Since the writable property is false, we reassign b, and the value of B does not change.

When creating objects, you can also use the get and set keywords to create accessor properties:

    var o = { get a() { return1}}; console.log(o.a); / / 1Copy the code

In this way, we understand that JavaScript objects are actually run as a “collection of properties,” with properties as strings and data property eigenvalues or accessor property eigenvalues as values.

An object is an index structure of attributes. For example, object O is the key. {writable: true, value: 1, configurable: true, enumerable: true} is value.

conclusion

It’s easy to see why JavaScript is not object-oriented. Because JavaScript design is very different from mainstream class-based design thinking.

In fact, this object system design although special, but it provides a run-time object system, also fully conforms to the specification of object-oriented design. So it’s also a serious object-oriented programming language.

If we can first remove some of the presuppositions of “class-based object-oriented” and look at JavaScript from its most naive object-oriented perspective, we can better understand its unique object-oriented design.

In the end, we should exploit its capabilities based on an understanding of its design ideas, rather than mechanically imitating other languages.


JavaScript in-depth series:

“var a=1;” What’s going on in JS?

Why does 24. ToString report an error?

Here’s everything you need to know about “JavaScript scope.

There are a lot of things you don’t know about “this” in JS

JavaScript is an object-oriented language. Who is for it and who is against it?

Deep and shallow copy in JavaScript

JavaScript and the Event Loop

From Iterator to Async/Await

Explore the detailed implementation of JavaScript Promises