Understand the browser environment, the use of JS programming after the basic concept, began to think about how to organize and optimize their own code, from the programming skills to improve the efficiency of development and maintenance work.

Related articles:

From the reconstruction of advanced front-end development (a) DOM operations
From refactoring advanced front-end development introduction (2) events and event objects
From refactoring advanced front-end development introduction (iii) event bubbling and event proxy

(4) Object oriented

DRY (Don’t Repeat Yourself) principle

JavaScript is a programming language, and like any other computer language, you need to be aware of the need to avoid repetitive code and logic as you code, and to constantly optimize your code.

In order not to write the seemingly large and reliable system, but actually redundant and sluggish code, bug hidden trouble, affect the team partners to read the code, the efficiency of collaborative development, and delay their own future optimization and iteration project.

Therefore, one of the most important principles is the DRY (Don’t Repeat Yourself) principle.

When you first write a piece of code and then write or paste the same code somewhere else, you should feel the urge to eliminate and extract duplicate code.

Wait until the third time, when the same code appears in another place, to consider taking action and extracting the common code rather than repeating it all over again.

Function reuse, common library

The most basic approach is to extract repetitive code into reusable functions.

Dialog box to display functions

For example, somewhere on the page there is a pop-up Dialog logic that writes code like this:

var $dialog1 = $('<div class="dialog-box">' + ' <p class="dialog-msg"></p>' + ' <a class="dialog-btn" </a>' + '</div>').text(' login succeeded! ') .on('click','[close-dialog]', function () { $(this).closest('.dialog-box').hide(); }).find('.dialog-msg').text(' Comment sent failed! '); $('body').append($dialog1);Copy the code

A similar Toast message was later added:

var $dialog2 = $('<div class="dialog-box">' + ' <p class="dialog-msg"></p>' + ' <a class="dialog-btn" Close - dialog > confirm < / a > '+' < / div > ') on (' click ', '[close - dialog]', function () {$(this). The closest (' dialog box - '). Hide (); }).find('.dialog-msg').text(' Comment sent failed! '); $('body').append($dialog2);Copy the code

This code is almost identical to the above, except for the prompt.

Obviously there is no need to repeat this, we can extract a generic showDialog display function:

function showDialog(msg) { var $dialog = $('<div class="dialog-box">' + ' <p class="dialog-msg"></p>' + ' <a Class = "dialog - BTN" close - dialog > confirm < / a > '+' < / div > ') on (' click ', '[close - dialog]', function () { $(this).closest('.dialog-box').hide(); }) .find('.dialog-msg') .text(msg); $('body').append($dialog); } showDialog(' Login successful! '); ShowDialog (' Comment sent failed! ');Copy the code

Extracting common functions is a basic programming idea.

In this way, when new messages need to be added later, or all the existing prompt messages need to be adjusted and fixed, there is no need to modify the scattered code, only one change, greatly improved efficiency.

Some of the code can even be used for more than one project, but also can be reused in the future project development, these functional logic can be extracted into a common code base, saving the time of future project development.

Abstract to an object/class

The idea above is to reuse the process of dealing with a class of transactions in the form of functions.

Is a relatively rudimentary reuse idea that becomes less effective as business logic becomes more complex.

The result is a js file that, when it reaches a certain size, has dozens or hundreds of functions, even though there is no duplicate code. Sorting out the order and relationships can be time-consuming and difficult to read.

And functional reuse does not deal well with attributes, states and the like.

For example, if you want to add drag handlers to the dialog box, you need to manually pass in many variables from the outside to handle the recording of coordinates, levels, open states and other attributes.

As a result, the logic and data related to the dialog box are scattered in different places in the file, and it is difficult to adjust the attributes when they need to be added or deleted.

Continue to add control logic in functional form, which is also easy to mix with other functions. Unsuspecting colleagues on projects can easily insert other functions to break them up.

The resulting project may work, but the internal code is a tangled spaghetti of interwoven code that is almost impossible to maintain.

So the former people of computer software engineering explored the idea of object-oriented programming.

Dialog box class definition

Let’s start with, what is a dialog box?

It should be a specific element that has specific coordinates, width, height, background color, etc., and can set its content, coordinates, control buttons, and other attributes of absolute positioning.

Is there a way to use a dialog box when we need to:

  • Create dialogs easily and quickly;
  • Calling the API allows you to adjust content, move it, show it, collapse the dialog;
  • And make different dialog box operation interface consistent, their data do not interfere with each other;
  • If necessary, can you quickly add new features to the existing interface?

All of this can be achieved through object-oriented inheritance, encapsulation, and polymorphism.

However, due to the particularity of JavaScript, polymorphism in duck mode is not obvious, not to mention. Let’s start with some basic concepts.

In the previous step, we abstracted the basic concept of a dialog box, that is, what we need a dialog box to be roughly.

Using object-oriented thinking, we can define a dialog box class as its member properties and methods.

In order to facilitate the new students to directly test the code in the browser, here uses ES5 class writing example:

As for the relationship between JavaScript prototype chains and aspect objects, this article will not go into depth to avoid confusion for beginners.

You can first learn to use the existing way, the prophet and then know why, through the practice of memory after in-depth understanding of the principle will be easier to use.

Function Dialog(options) {var self = this; // Create the corresponding DOM, This.$dom = $('<div class="dialog-box">' + '< p class="dialog-msg"></p>' + '< a class="dialog-btn") Close - dialog > confirm < / a > '+' < / div > ') on (' click ', '[close - dialog]', function () {self. Hide (); }); $('body').append(this.$dom); } // create a dialog. prototype = {// create a new dialog. prototype = {// create a new dialog. prototype = {// create a new dialog. prototype = {// create a new dialog. function (content) { this.$dom.find('.dialog-msg').text(content); }, // display dialog box show: function () {this.$dom.show(); Function () {this.$dom.hide(); }};Copy the code

First declare the constructor of the Dialog class Dialog, from which each Dialog will be built to a concrete instance.

By manipulating this, all dialogs have DOM objects to operate on, independent of each other. (For example, dialogs 1 and 2 have $DOM attributes. If you modify $DOM of dialogs 1, $DOM of dialogs 2 will not be affected, and vice versa).

Then, we added several Dialog prototype functions show, hide, and destroy. These functions are called class methods.

All dialogs can call these methods, and like constructors, they can also operate on this to achieve the effect that different instances do not interfere with each other.

Dialog box instance

The basic reusable dialog box class has been created and can be instantiated and used with new.

Var dialog1 = new Dialog(); // Set dialog1.setContent(' Login succeeded! '); // display dialog box 1 dialog1.show(); Var dialog2 = new Dialog(); // Set its content (does not affect dialog 1) dialog2.setContent(' Comment failed to send! '); // display dialog box 2 dialog2.show(); SetTimeout (function () {dialog2.hide(); }, 3000);Copy the code

What is the advantage of writing this over the showDialog function?

The first is centralization of logic and attributes, making it easy to maintain and extend members of the same class.

Use this to operate each instance, avoiding repeated parameter passing, no need to manually distinguish between different instances, flexible and convenient.

And through IDE analysis and inference, according to the type of the object, automatically give intelligent hints of attributes and methods, improve development efficiency, avoid searching in the function sea, and even confused call.

At present, the mainstream front-end automation has script packaging function, according to the class and basic logic of the project file structure, maintenance is very clear and convenient.

Collaborators can get an idea of the process by looking at the project structure.

For the top-level logic, only the main flow needs to be understood, while the low-level logic is wrapped in classes and transparent to the outside world.

Each file only needs to deal with its own related logic, the amount of code can be basically controlled within 400 lines, which is the most suitable level for maintenance and reading.

summary

Those of you who have experience with object-oriented development in other languages may wonder why the class life in JavaScript looks so strange.

This is because JavaScript object orientation is implemented based on prototypes rather than classes.

The most obvious difference is that there is no real class. Instead, it is based on an object instance, using the instance as a prototype for the constructor, and then calling the constructor to generate a new object that inherits from it.

This pattern is very flexible and suits the development pattern of the JavaScript dynamic scripting language.

However, it may be more difficult for beginners to understand. In practice, it is difficult to achieve a perfect inheritance extension and distinguish the functions of the prototype and instance, which can easily cause misunderstanding and confusion.

Therefore, ES6 provides a more convenient way to define class. Mainstream front-end development frameworks like React, Vue, and Angluar also recommend using the new ES6 writing method.

Once you’ve written ES5 mock classes to experience and understand them, you can feel the ease of defining classes in ES6 through the scaffolding of these frameworks or through Babel’s REPL.

If you are interested, try using ES6 to implement the dialog example above, and extend the width and height, coordinate properties, and corresponding resizing and position functions as part of this tutorial