“Objects” in JavaScript have always been less gregarious than in other languages.
Some people who are new to JavaScript object orientation often have some confusion when learning JavaScript object orientation:
- Why does JavaScript (up to ES6) have the concept of objects, but not the concept of classes, as other languages do?
- Why is it that JavaScript objects are free to add attributes, but other languages are not?
It has even been argued that JavaScript is not an “object-oriented language”, but an “object-based language”. This was once a popular saying, and in fact, no one I’ve met so far who holds it has been able to answer the question “how do you define object-oriented and object-based?”
In fact, both object-based and object-oriented adjectives appear in various versions of the JavaScript standard.
Let’s start by looking at the JavaScript standard’s object-based definition: “The language and host infrastructure are provided by objects, and a JavaScript program is a collection of objects that communicate with each other.”
The point here is not to express weak object orientation at all, but rather to express the importance of objects to the language.
So, in this article, I’m going to try to give you an understanding of what object orientation is and what object orientation is in JavaScript.
What is object orientation?
Let’s talk about what is the object first. Because of translation, it is difficult for us to understand the real meaning of “object” in Chinese context. In fact, Object is a general term for all things in English, which is connected with the abstract thinking of object-oriented programming.
However, the Chinese word “object” is not so universal. In the process of learning programming, we regard it as a professional term to understand.
In any case, we should realize that objects are not a figment of the computer field, but an abstraction generated by the human mode of thinking (thus object-oriented programming is also considered: a programming paradigm that is closer to the human mode of thinking).
So let’s start by looking at what objects are in the human mind.
The concept of objects was formed in early childhood, long before the concepts of values, procedures and so on that are commonly used in our programming logic. In infancy, we always first to realize an apple to eat (where one apple is an object), and then realize all apple can eat (and all of the apple, here is a class), and then we can realize the connection between the three apples and pears, and produces the concept of digital “3” (value).
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:
- Something that can be touched or seen;
- Something intelligible to the human mind;
- 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. In different programming languages, designers also use a variety of language features to describe objects abstractly. The most successful school is the use of “class” to describe objects, which gives birth to popular programming languages such as C++, Java and so on.
JavaScript, on the other hand, took an even less popular approach in its early days: archetypes (which I’ll focus on in the next article, just so you know). That’s one of the reasons I said earlier that it doesn’t fit in.
Unfortunately, for some corporate political reasons, JavaScript was ordered 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.” Make it “look more Like Java”.
Prior to ES6, a large number of JavaScript programmers tried to make JavaScript more class-based programming based on the prototype architecture, resulting in a number of so-called “frameworks” such as PrototypeJS and Dojo.
In fact, they became a kind of weird dialect of JavaScript, and even spawned a series of incompatible communities, which clearly had far more to gain than to lose.
If we are talking about objects from a runtime perspective, we are talking about the model in which JavaScript is actually run, since any code execution must be wrapped around the run-time object model.
Fortunately, however, from a runtime perspective, you don’t have to worry about these “class-based facilities” because the concept of a runtime class in any language is diluted.
First let’s look at how JavaScript designs the object model.
Characteristics of JavaScript objects
In my opinion, no matter what programming language we use, we should first understand the nature of the object (see Grandy Booch’s Object-oriented Analysis and Design). In summary, objects have the following characteristics.
- 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.
Let’s start with the first property, which is that 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.
So, JavaScript programmers know that any different JavaScript objects are not equal. We can look at the following code: o1 and O2 are identical objects at first glance, but they print false.
var o1 = { a: 1 };
var o2 = { a: 1 };
console.log(o1 == o2); // false
Copy the code
Regarding the second and third characteristics of objects, “state and behavior,” different languages use different terms to describe them abstractly, such as “member variables” and “member functions” in C++ and “properties” and “methods” in Java.
In JavaScript, state and behavior are abstracted uniformly as “properties.” Given that JavaScript designs functions as special objects (I’ll cover this in a later article, but I won’t go into detail here), behavior and state in JavaScript can be abstracted using properties.
The following code actually shows an example of common properties and functions as properties, where O is an object, D is a property, and f is a property. Although written differently, d and F are two common properties to JavaScript.
var o = {
d: 1,
f() { console.log(this.d); }};Copy the code
So, to sum up, in JavaScript, the state and behavior of objects are abstracted as properties. If you’ve ever used Java, don’t be surprised that, despite the differences in design, both nicely represent the basic characteristics of objects: identity, state, and behavior.
On the basis of realizing the basic characteristics of objects, I think that objects in JavaScript are unique in that they are highly dynamic because JavaScript gives users the ability to add state and behavior to objects at run time.
As an example, JavaScript allows the runtime to add properties to objects, unlike most class-based, static object designs. If you’ve ever used Java or any other language, you’ll feel the same way.
The following code shows how the runtime can add attributes to an object. I define an object O, and after I define it, I add its attribute B, which is perfectly fine.
var o = { a: 1 }; o.b = 2; console.log(o.a, o.b); / / 1. 2Copy the code
To improve abstraction, JavaScript properties are designed to be more complex than other languages, providing data properties and getter/setter properties.
Two classes of properties for JavaScript objects
Properties are not simply names and values for JavaScript. 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 allow properties to execute code while they are being read and written. Accessor properties allow users to get completely different values when they write and read properties. Accessor properties can be considered syntactic sugar for functions.
The code that normally defines a property creates a data property. Writable, Enumerable, and different default is true. We can view this using the built-in getOwnPropertyDescripter function, 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
So we’re using two syntax here to define the property, and when we’re done defining the property, we’re using JavaScript apis to look at the property, and we can see that all the properties that we’re defining are data properties, Writeable, Enumerable, and different are all default values which are true.
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 used Object.defineProperty to define the property, which changes the writable and Enumerable properties of the property.
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 an object, you can also use the get and set keywords to create accessor properties as follows:
var o = { get a() { return1}}; console.log(o.a); / / 1Copy the code
An accessor property, unlike a data property, executes a getter or setter function every time it is accessed. Here our getter returns 1, so O.A gets 1 every time.
In this way, we understand that JavaScript objects are actually run as a “collection of properties” that take a string or Symbol as a key and a data attribute or accessor attribute as a value.
An object is an index structure of attributes (an index structure is a common type of data structure, which can be understood as a dictionary that can quickly find values using keys). Let’s take the object O above. You can imagine that “A” is key.
{writable: true, value: 1, configurable: true, enumerable: true} is value. We introduced the Symbol type in an earlier class on typing, and the ability to use Symbol as a property name is a feature of JavaScript objects.
At this point, if you understand the characteristics of objects, it is not difficult to understand the question I raised at the beginning.
You can even see why JavaScript is not object-oriented. This is because the object design of JavaScript is very different from the current mainstream class-based object orientation.
In fact, although this object system design is unique, JavaScript provides a fully run-time object system, which allows it to mimic most object-oriented programming paradigms. (In the next class we’ll introduce you to two object-oriented programming paradigms in JavaScript: Class-based and prototype-based), so it is also a legitimate object-oriented language.
The JavaScript language standard also explicitly states that JavaScript is an object-oriented language, and I think the standard says so, because of JavaScript’s highly dynamic object system.
Therefore, we should fully exploit its capabilities based on understanding its design ideas, rather than mechanically imitating other languages.
conclusion
In order to understand JavaScript objects, we must clear our mind of “object-oriented based on class” related knowledge, back to human cognition of objects and object-oriented language independent basic theory, we can understand the idea of JavaScript object-oriented design.
In this article, I start from the basic theory of objects, and you clear up some basic concepts about objects, analysis of JavaScript object design ideas. Then, from a runtime perspective, I introduced the concrete design of JavaScript objects: a highly dynamic set of properties.
A lot of people think about JavaScript objects in terms of what they already know as “objects,” and the result is, of course, “chaos.”
From: Geek time, if any infringement please contact delete.