Traditional operas

JavaScript skill holders must have asked this question:

Is JavaScript an object-oriented language?

Your expected answer should be “yes” or “no”.

But unfortunately, you don’t get that simple answer!

After you’ve read about it, you’re told:

JavaScript is not a pure object-oriented language!

WTF!!!! Why not pure? Can you be pure? ! We like pure, not chaos!

.

In fact, there really isn’t much need for a rigid definition. The story behind the definition is what matters!

By the end of this article, you will understand what this “chaos” is, where it comes from, and where it’s going!

Writing is not easy, encourage a lot. Like and watch. Make it a habit. 👍 👍 👍

The class design pattern

As we all know, object-oriented has three characteristics: encapsulation, inheritance and polymorphism.

  1. The so-called encapsulation, namely the objective things into abstract classes.

  2. Inheritance is the ability of a child class to inherit from its parent class.

  3. Polymorphism means that a subclass can override the generic behavior of its inherited parent class with more specific behavior.

The concept of “class” is the most important of all! [class] describes a form of code organization that is used in software to model real-world problem domains.

Here’s an example:

Just like our real house, you want to build an “office building”, or a “residential building”, or a “shopping mall”, you have to find the “office building”, “residential building”, “shopping mall” 【 design blueprint 】.

But the blueprint is just an architectural plan, not a real building. To implement the building in the real world, it is up to the construction workers to [copy] the characteristics of the blueprint (such as length, width, height, function) into the real world.

Here the blueprint is the class, the copy process is the instantiation, and the instance is the object.

A class usually has a constructor with the same name inside it, and its pseudo-code might look something like this:

Class Mall {// garage = num} class Mall {// garage = num} shop(goods){// output("We can buy: }} // Most constructors need to be called with new so that the language engine knows that you want to construct a new instance of the class. Vanke = new Mall(1) // Vanke has 1 underground garage vanke.shop("KFC") // "We can buy: KFC"Copy the code

Java is a typical object-oriented language. Based on “classes,” let’s take a look at the following Java code to understand inheritance and polymorphism.

Public abstract class Animal{// abstract class abstract void sound(); } public class extends Animal{public void sound(){sound(" cluck "); }} public class extends Animal{public void Duck extends Animal{public void sound(){sound(" quack quack "); } } public static void main(String args[]){ Aninal chicken = new Chicken(); Animal duck = new Duck(); chicken.sound(); // Duck.sound (); // quack quack}Copy the code

Both chickens and ducks belong to the animal class and can produce calls (inheritance), but they can produce different calls (polymorphism), which is easy to understand.

Inheritance allows a child class to acquire all the functions of its parent class. Polymorphism can make the program have good extension;

Recall: In JS, we might write:

var Duck = function () {}; var Chicken = function () {}; Var makeSound = function (animal){if(animal instanceof Duck){console.log(" quack quack "); }else if(animal instanceof Chicken){console.log(" animal instanceof Chicken "); }}; makeSound(new Duck()); makeSound(new Chicken());Copy the code

There’s no inheritance, there’s no polymorphism. This is the main culprit of “not clean” code!

  • Here’s a question. If I don’t have to judge, what else can I write?

In VUE2, we might write:

export default { data() { return { }, mounted(){ this.Chicken() this.Duck() }, Methods :{funtion AnimalSound(sound){console.log(" call :" + sound)}, funtion Chicken(){this.animalSound (" clack ")}, Funtion Duck(){this.animalsound (" quack quack ")}}Copy the code

Nested calls to functions like this are common. No inheritance, no polymorphism, not even the most fundamental “class”? !

(In fact, each Function is a Function object. As stated in the original definition, an object is an instance of a class, so you can see “class” in a function!)

In JavaScript, functions become first class citizens! Functions seem to do everything! It can return an object, it can assign a value to a variable, it can be an array entry, it can be a property of an object……

But this is clearly not a “class design pattern.”

The “class design pattern” means a copy of the “design blueprint”, which is almost invisible in the context of various JS function calls.

“Prototype” design pattern

In fact, as we all know, JS is also able to do [inheritance] and [polymorphism]! It’s just that it’s not a class copy, it’s a prototype chain delegate!

A picture to understand the prototype chain?

Look not to understand? That’s ok, remember these two sentences again:

  1. The constructor of an object’s display prototype points to the object itself (familiar? Seen in this article?)
  2. The implicit stereotype of an object points to the display stereotype of the function that constructed the object.

JS is not instantiated by writing a constructor of the same name inside the class. Its constructor is on the prototype! This more exotic code ingestion mechanism is different from the code reuse system of classical classes.

Here’s another classic question, right? What happens to the JS New operation?

Is it copying like a class?

The answer is no!

When JS accesses a property or method of an object, first look in the object itself, if not, then look in the prototype, if still can not find, then further look in the prototype of the prototype, until the end of the prototype chain. Copying is not what it does, this is how it looks! The relationship between objects is more like a delegate relationship, like looking for something, you can’t find it in me, okay? Look for over the other person that has entrust relation, cannot find again, look for…… over the person that entrusts relation All the way to the end, I can’t find it at the end, pointing to null.

So: unlike object-oriented languages, JavaScript does not have classes that serve as abstract patterns or blueprints for objects. There are only objects in JavaScript, and objects directly define their own behavior. The relationship between objects is the delegate relationship, which is an extremely powerful design pattern. In your mind’s eye objects are not organized vertically in a superclass to subclass relationship, but side-by-side with delegate associations in any direction!

But you can also use this delegate relationship to simulate classic object-oriented architecture: classes, inheritance, polymorphism. But the “class” design pattern is just an optional design pattern that you may or may not emulate!

The reality is that ES6 class simulates for us:

class Widget { constructor(width,height) { this.width = width || 50; this.height = height || 50; this.$elem = null; } render($where){ if (this.$elem) { this.$elem.css( { width: this.width + "px", height: this.height + "px" }).appendTo( $where ); } } } class Button extends Widget { constructor(width,height,label) { super( width, height ); this.label = label || "Default"; this.$elem = $( "<button>" ).text( this.label ); } render($where) { super.render( $where ); this.$elem.click( this.onClick.bind( this ) ); } onClick(evt) { console.log( "Button '" + this.label + "' clicked!" ); }}Copy the code

It looks very nice, very clear!

There is no.prototype to show the complex writing of the prototype, and no need to set the.proto implicit prototype. Inheritance and polymorphism also seem to be implemented with extends and super.

However, this is just the grammar sugar trap! JS has no class, no copy, its mechanism is “delegate”.

Classes do not have the static copy behavior of traditional class-oriented languages. If you intentionally or unintentionally change the parent class, the subclass will also be affected.

For example:

class C { constructor() { this.num = Math.random(); } rand() { console.log( "Random: " + this.num ); } } var c1 = new C(); c1.rand(); / / "Random: 0.4324299..." C.prototype.rand = function() { console.log( "Random: " + Math.round( this.num * 1000 )); }; var c2 = new C(); c2.rand(); // "Random: 867" c1.rand(); // "Random: 432" -- oh!Copy the code

The ES6 class confuses the “class design pattern” with the “prototype design pattern.” Its biggest problem is that its syntax sometimes leads you to think that once you define a class, it becomes a static definition of something that will be instantiated in the future. You’ll completely ignore that a Class is an object, a concrete thing that you can interact with directly. Of course, it also has other details, such as the property override method, super binding issues, you are interested in learning.

In general, ES6’s classes pretend to be a nice solution to a syntax problem, but actually make the problem harder to solve and JavaScript harder to understand. — JavaScript You Don’t Know

summary

  • Class design mode has constructors that hang from classes of the same name. Class inheritance means copy, polymorphism means copy + customization.

  • The prototype design pattern has constructors hanging on the prototype, and the search for the prototype is a bottom-up delegate relationship.

  • The class Design pattern does not support changes after the class definition.

  • The “prototyping pattern” is very dynamic, and the definition of any object can be changed. This fits perfectly with the dynamic nature of JavaScript as a scripting language!

You can use “prototype design pattern” to simulate “design like pattern”, but this is more likely to be a loss than a gain.

Finally, if asked again: Is JavaScript an object-oriented language?

If you understand this article, you can focus on “class design pattern” and “prototype design pattern” to blow up.

If you don’t understand the text, just recite the following answer……

Follow the public account “Nuggets Anthony”, continue to output ING!!

A little tired of writing business code recently 😭…… Who can help?

reference

  • Named function expression probe
  • What’s the difference between functional and object-oriented programming?
  • tutorials/js.mp
  • JavaScript you don’t know
  • JavaScript lightweight functional programming