js Advanced+Object Oriented+ES6

JavaScript Object Oriented

1. Introduction to object-oriented programming

1.1 Two Programming Ideas

  • Process-oriented is to analyze the steps needed to solve a problem, and then use functions to implement these steps step by step, one by one, when used in turn. Process-oriented is to solve problems step by step.

    Advantages: Higher performance than object-oriented, suitable for things closely related to hardware, such as single-chip computers

    Disadvantages: No object-oriented, easy to maintain, easy to reuse, easy to expand

  • Object-oriented is to decompose a transaction into an object, and then divide the work and cooperation among the objects. Object-oriented divides problems by object functionality, not by steps.

    Advantages: Easy to maintain, reuse, and expand. Due to the characteristics of encapsulation, inheritance and polymorphism, a low-coupling system can be designed, which makes the system more flexible and easy to maintain.

    Disadvantages: lower performance than process-oriented

2. Classes and objects in ES6

2.1 Object

In JavaScript, objects are an unordered collection of related properties and methods, everything is an object, such as strings, numbers, arrays, functions, and so on.

Objects are made up of properties and methods:

  • Attributes: The characteristics of things, expressed as attributes in objects (common nouns)

  • Method: The behavior of an object, represented by a method in the object (common verbs)

class 2.2

A new concept for classes was added in ES6 to instantiate objects by declaring a class with the class keyword.

  • Class abstracts the public part of an object and refers generally to a large class

  • An object refers to a particular object, instantiating a specific object through a class

2.3 Create Classes

// grammar
class name {
  // class body
}
//Create an instance
var xx = new name();     

Note: Classes must use new instantiated objects

Class 2.4 constructor constructors

The constructor() method is the class's constructor (default method), which is used to pass parameters, return instance objects, and automatically invoke the method when an object instance is generated by the new command. If no definition is displayed, a constructor() is automatically created for us inside the class.

// grammar
class Person {
  constructor(name,age) {   // Constructor constructor
      this.name = name;
      this.age = age;
    }
}       
// Create an instance
var ldh = new Person('Lau Andy', 18); 
console.log(ldh.name)    

2.5 Class Add Method

//grammar
class Person {
  constructor(name,age) {   // Constructor constructor constructor
      this.name = name;
      this.age = age;
    }
   say() {
      console.log(this.name + 'Hello');
   }
} 
// Create an instance
var ldh = new Person('Lau Andy', 18); 
ldh.say()   

Note: Methods cannot be separated by commas, and methods do not need to add function keywords.

3. Class Inheritance

3.1 Inheritance

Subclasses can inherit some of the properties and methods of the parent class.

//grammar
class Father{   // Parent Class
} 
class  Son extends Father {  // Subclass inherits parent class
}      
// case
class Father {
      constructor(surname) {
        this.surname= surname;
      }
      say() {
        console.log('Your last name is' + this.surname);
       }
}
class Son extends Father{  // The subclass then inherits the properties and methods of the parent class

}
var damao= new Son('Liu');
damao.say();      

3.2 super keyword

The super keyword is used to access and invoke functions on the object's parent class. You can call either the parent's constructor or the parent's normal function

  • Call the parent class's constructor
// grammar
class Person {   // Parent Class
      constructor(surname){
         this.surname = surname;
     }
} 
class  Student extends Person {       // Subclass inherits parent class
     constructor(surname,firstname){
          super(surname);             // Call the constructor(surname) of the parent class
		  this.firstname = firstname; // Define properties unique to subclasses
     }
}       
// case
 class Father {
    constructor(surname) {
        this.surname = surname;
     }
    saySurname() {
      console.log('My last name is' + this.surname);
    }
}
class Son extends Father { // The subclass then inherits the properties and methods of the parent class
    constructor(surname, fristname) {
         super(surname);   // Call constructor(surname) of parent class
         this.fristname = fristname;
     }
    sayFristname() {
         console.log("My name is:" + this.fristname);
    }
}
var damao = new Son('Liu', "Dewar");
damao.saySurname();
damao.sayFristname();      

Note: Subclasses that use super in constructors must precede this (they must call the parent class's constructor first, and use the subclass constructor)

  • Call normal functions of parent class
class Father {
     say() {
         return 'I'm daddy';
     }
}
class Son extends Father { // The subclass then inherits the properties and methods of the parent class
     say() {
          // Super. Say() super calls the method of the parent class
          return super.say() + 'Son of';
     }
}
var damao = new Son();
console.log(damao.say());       

3.3 Three points of attention

  1. There is no variable promotion for classes in ES6, so classes must be defined before objects can be instantiated through classes
  2. Common attributes and methods within a class must be used with this
  3. This inside the class points to the problem: This inside the constructor points to the instance object, and this inside the method points to the caller of the method

Constructors and Prototypes

1. Constructors and Prototypes

1.1 Overview

Class concepts exist in typical OOP languages, such as Java, where classes are templates for objects and objects are instances of classes, but before ES6, the concept of classes was not introduced in JS. Prior to ES6, objects were not created based on classes, but rather defined objects and their characteristics using a special function called a constructor function.

Objects can be created in three ways:

  1. Object Literal
  2. new Object()
  3. Custom Constructor

1.2 Constructor

Constructors are special functions that are used to initialize objects, that is, to assign initial values to object member variables, which are always used with new. We can extract some common properties and methods from the object and encapsulate them in this function.

In JS, there are two things to note when using constructors:

  1. Constructors are used to create a class of objects whose initial letters are capitalized
  2. Constructors make sense when used with new

new does four things when it executes:

1. Create a new empty object in memory.

(2) Let this point to this new object.

(3) Execute the code inside the constructor to add properties and methods to this new object.

(4) Return this new object (so there is no need for return in the constructor).

JavaScript constructors can have members added either on the constructor itself or on this inside the constructor. Members added in these two ways are called static members and instance members, respectively.

  • Static members: Members added to the constructor book are called static members and can only be accessed by the constructor itself

  • Instance members: Object members created inside the constructor are called instance members and can only be accessed by instantiated objects

1.3 Constructor Problems

The constructor method is useful, but it wastes memory.

function Star(uname, age) {
    this.uname = uname;
    this.age = age;
    this.sing = function() {
        console.log('I can sing');
    }
}
var ldh = new Star('Lau Andy', 18);
var zxy = new Star('Jacky Cheung', 19);

1.4 Constructor prototype

Constructors are assigned functions through prototypes that are shared by all objects.

JavaScript specifies that each constructor has a prototype property that points to another object. Notice that this prototype is an object, and that all its properties and methods are owned by the constructor.

We can define those invariant methods directly on the prototype object so that all instances of the object can share them.

  • A prototype is an object, which we also call a prototype
  • The role of prototypes is to share methods

1.5 Object Prototype_u proto u

Every object will have an attribute_u proto u The prototype object pointing to the constructor, so we can use the properties and methods of the prototype object of the constructor because the object has u proto u The existence of prototypes.

  • _u proto u Object prototype is equivalent to prototype
  • _u proto u The meaning of an object prototype is to provide a direction, or a route, for the object's lookup mechanism, but it is a non-standard property, so this property can not be used in actual development. It only points internally to the prototype of the prototype object.

1.6 constructor constructor

Object Prototype (u proto u) There is an attribute constructor attribute inside the prototype object of the and constructor, which we call a constructor because it refers to the constructor itself.

The constructor is primarily used to record which constructor the object references, allowing the prototype object to point back to the original constructor.

Normally, the object's methods are set in the prototype object of the constructor. If there are multiple object methods, we can assign values to the prototype object as an object, but this will overwrite the original content of the constructor prototype object, so that the modified prototype object constructor will no longer point to the current constructor. At this point, we can add a constructor to the modified prototype object to point to the original constructor.

        function Star(uname, age) {
            this.uname = uname;
            this.age = age;
        }
        // In many cases, we need to manually use the constructor property to refer back to the original constructor
        // Star.prototype.sing = function() {
        //     console.log('I can sing');
        // };
        // Star.prototype.movie = function() {
        //     console.log('I'll play a movie');
        // }
        Star.prototype = {
            // If we modify the original prototype object and assign it to an object, we must manually use the constructor to refer back to the original constructor
            constructor: Star,
            sing: function() {
                console.log('I can sing');
            },
            movie: function() {
                console.log('I'll play a movie');
            }
        }
        var ldh = new Star('Lau Andy', 18);
        var zxy = new Star('Jacky Cheung', 19);
        console.log(Star.prototype);
        console.log(ldh.__proto__);
        console.log(Star.prototype.constructor);
        console.log(ldh.__proto__.constructor);

1.7 Relationships among constructors, instances, and prototype objects

1.8 Prototype Chain

1.9 Object Member Lookup Rules

  1. When accessing the properties (including methods) of an object, first find out if the object itself has the property.
  2. If not, look for its prototype (that is, the prototype object that u proto u points to).
  3. Find the prototype of the prototype object (the prototype object of the Object) if you haven't already done so.
  4. And so on until Object is found (null).
  5. _u proto u The meaning of object prototypes is to provide a direction, or a route, for object member lookup mechanisms.

1.10 Prototype object this points to

this in the constructor points to the instance object.

Inside the prototype object is a method, where this points to the caller of the method, which is the instance object.

1.11 Extending built-in objects

You can extend your customization of the original built-in objects by prototyping them. For example, add the ability to customize the sum of even numbers to an array.

        // Application extension of built-in object methods for prototype objects
        Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        };
        // Array.prototype = {
        //     sum: function() {
        //         var sum = 0;
        //         for (var i = 0; i < this.length; i++) {
        //             sum += this[i];
        //         }
        //         return sum;
        //     }
        // }
        var arr = [1, 2, 3];
        console.log(arr.sum());
        console.log(Array.prototype);
        var arr1 = new Array(11, 22, 33);
        console.log(arr1.sum());

**Note: ** Arrays and string built-in objects cannot override the operation Array for prototype objects. Prototype = {}, can only be Array.prototype. XXX = the way function (){}.

2. Inheritance

We were not given extends inheritance prior to ES6. We can implement inheritance through constructor + prototype object simulation, which is called composite inheritance.

2.1 call()

Call this function and modify the this point at which the function runs

fun.call(thisArg, arg1, arg2, ...) 
  • thisArg: The object to which the function this is currently called
  • arg1, arg2: Other parameters passed

2.2 Borrowing constructors to inherit parent type properties

Core Principle: By pointing this of the parent type to this of the subtype through call(), the subtype can inherit the attributes of the parent type.

    // Parent Class
    function Person(name, age, sex) {
      this.name = name;
      this.age = age;
      this.sex = sex;
    }
    // Subclass
    function Student(name, age, sex, score) {
      Person.call(this, name, age, sex);  // At this point the parent class's this points to the subclass's this and this function is called
      this.score = score;
    }
    var s1 = new Student('zs', 18, 'male', 100);
    console.dir(s1); 

2.3 Borrowing prototype objects to inherit parent type methods

Normally, the object's methods are set in the prototype object of the constructor, and the parent method cannot be inherited through the constructor.

Core Principles:

  1. Extract the methods shared by the subclass so that the prototype prototype object of the subclass = the new parent class ()
  2. Re-point the constructor of the subclass to the constructor of the subclass
        // Borrowing parent constructor inheritance properties

        // 1. Parent Constructor
        function Father(uname, age) {
            // this points to an object instance of the parent constructor
            this.uname = uname;
            this.age = age;
        }
        Father.prototype.money = function() {
            console.log(100000);
        };

        // 2. Subconstructor 
        function Son(uname, age, score) {
            // this points to an object instance of a sub-constructor
            Father.call(this, uname, age);
            this.score = score;
        }
        // Son.prototype = Father.prototype; This has a problem with direct assignment, and if you modify a child prototype object, the parent prototype object changes with it.
        Son.prototype = new Father();
        // If you modify the prototype object as an object, don't forget to use the constructor to point back to the original constructor
        Son.prototype.constructor = Son;
        // This is a special method for sub-constructors
        Son.prototype.exam = function() {
            console.log('Children have exams');
        }

        var son = new Son('Lau Andy', 18, 100);
        console.log(son);
        console.log(Father.prototype);
        console.log(Son.prototype.constructor);

Essential: A child prototype object is equal to an instantiated parent, because opening up additional space after the parent is instantiated will not affect the original parent prototype object

3. The nature of classes

  1. class is essentially a function.
  2. All methods of the class are defined on the prototype property of the class.
  3. Instances of class creation with u proto u The prototype prototype object pointing to the class.
  4. The vast majority of ES6's class functionality can be achieved by ES5, and the new class writing simply makes the object prototype's writing clearer and more like the grammar of object-oriented programming.
  5. The ES6 class is actually grammatical sugar.
  6. Grammatical sugar: Grammatical sugar is a convenient way to write. Simply understand, there are two ways to achieve the same function, but one way to write more clearly and conveniently is grammatical sugar.

4. New methods in ES5

ES5 has added some new methods for manipulating arrays or strings, which include:

  • Array method

  • String Method

  • Object Method

4.1 Array Method

Iterative (traversal) methods: forEach(), map(), filter(), some(), every()

forEach()

array.forEach(function(currentValue, index, arr))
  • currentValue: The value of the current item in the array

  • Index: The index of the current item of the array

  • arr: the array object itself

map()

var numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);

function myFunction(value, index, array) {
  return value * 2;
}
  • The map() method creates a new array by executing a function on each array element.
  • The map() method does not perform functions on array elements that have no values.
  • The map() method does not change the original array.

filter()

array.filter(function(currentValue, index, arr))
  • The filter() method creates a new array in which elements are primarily used to filter arrays by checking all eligible elements in the specified array

  • It returns a new array directly

  • currentValue: The value of the current item in the array

  • Index: The index of the current item of the array

  • arr: the array object itself

some()

array.some(function(currentValue, index, arr))
  • The some() method is used to detect whether an element in an array meets a specified condition. (Find if there are elements in the array that meet the criteria)
  • It returns a Boolean value, which returns true if the element is found, and false if it is not found.
  • If the first element that meets the criteria is found, the loop is terminated and the search is no longer continued.
  • currentValue: The value of the current item in the array
  • Index: The index of the current item of the array
  • arr: the array object itself

every()

var numbers = [45, 4, 9, 16, 25];
var allOver18 = numbers.every(myFunction);

function myFunction(value, index, array) {
  return value > 18;
}
  • The every() method checks that all array values pass the test. (Does each item in the array meet the requirements)
  • Return true or false

4.2 String Method

The trim() method removes white space characters from both ends of a string.

str.trim()

The trim() method does not affect the original string itself; it returns a new string.

4.3 Object Method

  1. Object.keys() is used to get all the properties of the object itself
Object.keys(obj)
  • The effect is similar to for...in

  • Returns an array of attribute names

  1. Object.defineProperty() defines a new property in an object or modifies an existing property. (Understanding)
Object.defineProperty(obj, prop, descriptor)
  • obj: required. Target object
  • prop: required. Name of the property to be defined or modified
  • descriptor: required. Attributes owned by the target attribute

Object.defineProperty() third parameter descriptor description: Write as object {}

  • Value: Set the value of the property to undefined by default
  • writable: Whether the value can be overridden. true | false defaults to false
  • enumerable: Whether the target attribute can be enumerated. true | false defaults to false
  • configurable: can the target attribute be deleted or can the attribute true | false be modified again by default

function

1. Definition and invocation of functions

How 1.1 functions are defined

  1. Custom functions (named functions)

    function fn() {};
    
  2. Function expression (anonymous function)

    var fun = function() {};
    
  3. Using new Function('Parameter 1','Parameter 2','Function Body') is inefficient, inconvenient to write, and less used

    var f = new Function('a','b','console.log(a+b)');
    f(1,2);
    

All functions are actually instances (objects) of Function.

Functions also belong to objects

Call method of 1.2 function

  1. General function

    function fn() {};
    fn();
    fn.call();
    
  2. Method of object

    var o = {
        sayHi:function(){
            
        }
    }
    o.sayHi();
    
  3. Constructor

    function Star(){};
    new Star();
    
  4. Bind Event Function

    btn.onclick = function(){}; //Click the button to invoke
    
  5. Timer Functions

    setInterval(function(){},1000); //Timer automatically called once a second
    
  6. Execute function immediately

    (function(){
        
    })(); //Immediate execution of a function is called automatically
    

2. this

Direction of 2.1 this

The direction of these this is determined when the function is called. Different ways of calling determine the direction of this, which generally points to the caller.

  1. The normal function this points to window

    function fn() {};
    fn();
    fn.call();
    window.fn() //Complete Writing
    
  2. Object's method this points to the object to which the method belongs o

    var o = {
        sayHi:function(){
            
        }
    }
    o.sayHi();
    
  3. Constructor this points to instance object ldh

    The method inside the prototype object also points to the instance object ldh

    function Star(){};
    Star.prototype.sing = function(){
        
    }
    var ldh = new Star();
    
  4. The bound event function this points to the bound event object (the caller of the function) btn

    btn.onclick = function(){}; //Click the button to invoke
    
  5. The timer function this also points to window

    setInterval(function(){},1000); //Timer automatically called once a second
    
  6. Immediate execution of function this also points to window

    (function(){
        
    })(); //Immediate execution of a function is called automatically
    

2.2 Change the this point inside the function

JavaScript provides us with some special functional methods to help us handle this pointing problem more elegantly within a function. There are three commonly used methods: bind(), call(), apply().

  • call method and its application
  1. Call function
  2. Changing the this direction within a function
  3. The primary role is to achieve inheritance
        // 1. call()
        var o = {
            name: 'andy'
        }
        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        };
        fn.call(o, 1, 2); // Point to object o

        // call The first callable function The second can change the this point within the function
        // The main function of call is to implement inheritance
        function Father(uname, age, sex) {
            this.uname = uname;
            this.age = age;
            this.sex = sex;
        }
        function Son(uname, age, sex) {
            Father.call(this, uname, age, sex);
        }
        var son = new Son('Lau Andy', 18, 'male');
        console.log(son);
  • apply method and its application
        // 2. Application () Meaning of application or application
        var o = {
            name: 'andy'
        };
        function fn(arr) {
            console.log(this);
            console.log(arr); // 'pink'
        };
        fn.apply(o, ['pink']); // Point to object o

        // 1. It is also the second call to a function that can change the this direction inside the function
        // 2. But his argument must be an array (pseudo array)
        // 3. The main application of apply is that we can use apply, for example, to maximize an array with the help of math built-in objects 
        // Math.max();
        var arr = [1, 66, 3, 99, 4];
        var arr1 = ['red', 'pink'];
        // var max = Math.max.apply(null, arr);
        var max = Math.max.apply(Math, arr);
        var min = Math.min.apply(Math, arr);
        console.log(max, min);
  • bind method and its application
    <button>click</button>
    <button>click</button>
    <button>click</button>

    <script>        
        // 3. Meaning of binding or binding
        var o = {
            name: 'andy'
        };
        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        };
        var f = fn.bind(o, 1, 2);
        f();
        
        // 1. Not calling the original function can change the this direction inside the original function
        // 2. Returns the new function that is generated when the original function changes this
        // 3. If there is a function we don't need to call it immediately, but we want to change the this inside the function to point to bind at this time.
        // 4. We have a button that will be disabled when we click it and then turned on after 3 seconds
        // var btn1 = document.querySelector('button');
        // btn1.onclick = function() {
        //     this.disabled = true; // This this points to the btn button
        //     // var that = this;
        //     setTimeout(function() {
        //         // that.disabled = false; // this inside the timer function points to window
        //         this.disabled = false; // The this inside the timer function now points to btn
        //     }.bind(this), 3000;// This this points to the btn object
        // }
        var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false;
                }.bind(this), 2000);
            }
        }
    </script>
  • call apply bind summary

Same:

You can change the this direction inside a function

The difference:

  1. Call and apply call functions, but bind does not call functions
  2. call and apply pass different parameters, apply parameters are arrays

Main application scenarios

  1. call inheritance
  2. apply is often associated with arrays, such as minimizing the maximum of an array with the aid of a mathematical object
  3. bind does not call a function but wants to change this to something like changing this inside a timer

3. Strict Mode

3.1 Turn on strict mode

Strict patterns can be applied to the entire script or to individual functions. Therefore, when using strict mode, we can divide it into two cases: opening strict mode for scripts and opening strict mode for functions.

    <!-- Turn on strict mode for scripts -->
    <script>
        'use strict';
        //   The following js code executes in strict mode
    </script>
    <script>
        (function() {
            'use strict';
        })();
    </script>

    <!-- Turn on strict mode for functions -->
    <script>
        // Just turn on strict mode for the fn function at this point
        function fn() {
            'use strict';
            // The following code executes in strict mode
        }
        function fun() {
            // Inside or in normal mode
        }
    </script>

Changes in strict mode

        'use strict';

        // 1. Our variable names must be declared before they can be used
        // num = 10;
        // console.log(num);
        var num = 10;
        console.log(num);

        // 2. We cannot delete declared variable syntax errors at will
        // delete num;

        // 3. this is undefined in the global scope function in strict mode.
        // function fn() {
        //     console.log(this); // undefined. 
        // }
        // fn();

        // 4. In strict mode, if the constructor does not make a new call, this points to undefined, which will cause an error if it is assigned a value.
        // function Star() {
        //     this.sex ='male';
        // }
        // // Star();
        // var ldh = new Star();
        // console.log(ldh.sex);

        // 5. Timer this or pointing to window 
        // setTimeout(function() {
        //     console.log(this);
        // }, 2000);
        // a = 1;
        // a = 2;

        // 6. Duplicate names are not allowed for parameters inside functions in strict mode
        // function fn(a, a) {
        //     console.log(a + a);
        // };
        // fn(1, 2);
        function fn() {}

		// 7. Functions must declare that functions are allowed to be nested at the top level but not in non-functional code blocks such as if for

For more strict mode requirements, see: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

4. Higher Order Functions

A higher-order function is a function that operates on other functions, receiving a function as a parameter or outputting a function as a return value

        // Higher-order function can be passed as a parameter
        function fn(a, b, callback) {
            console.log(a + b);
            callback && callback();
        }
        fn(1, 2, function() {
            console.log('I was last called');
        });
        $("div").animate({
            left: 500
        }, function() {
            $("div").css("backgroundColor", "purple");
        })

Functions are also a data type that can be passed as parameters to another function, most typically as callback functions. Similarly, functions can be passed back as return values.

5. Closure

5.1 Variable Scope

Variables are divided into two types according to scope: global and local.

  1. Global variables can be used inside a function.

  2. Local variables cannot be used outside a function.

  3. When the function is executed, local variables in this scope are destroyed.

5.2 What is a closure

closure refers to a function that has access to variables in the scope of another function (a scope can access local variables of another function)

        // A closure is a function that has access to variables in the scope of another function.
        // Closure: We fun this function scope accessed the local variable num inside another function fn
        function fn() {
            var num = 10;
            function fun() {
                console.log(num);
            }
            fun();
        }
        fn();

Role of 5.3 Closure

Closure: Extending the scope of a variable

        // A closure is a function that has access to variables in the scope of another function.
        // Local variables where one scope can access another function 
        // Our scopes outside fn can access local variables inside fn
        // The primary role of closures: They extend the scope of variables and are also a use of higher-order functions.
        function fn() {
            var num = 10; // Variable num All functions will be destroyed after use

            // function fun() {
            //     console.log(num);
            // }
            // return fun;
            
            return function() {
                console.log(num);
            } // return is the primary implementation principle of closures
        }
        var f = fn();
        f();
        // Be similar to
        // var f = function() {
        //         console.log(num);
        //     }
        // var f =  function fun() {
        //         console.log(num);
        //     }

Application of 5.4 Closure

Click li to output the index number of the current li (classic interview cases)

        // Closure Application - Click li to output the index number of the current li

        // 1. We can take advantage of dynamically adding attributes
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            lis[i].index = i;
            lis[i].onclick = function() {
                // console.log(i);
                console.log(this.index);
            }
        }

        // 2. Use closures to get the index number of the current small li
        for (var i = 0; i < lis.length; i++) {
            // Four immediate execution functions were created using the for loop
            // Executing a function immediately also becomes a small closure because any function within the function immediately executes can use its i variable
            (function(i) { 
                // console.log(i);
                lis[i].onclick = function() {
                    console.log(i);
				// Closures are not necessarily good either. In this case, if you don't click on Li all the time, I won't be released, causing a memory leak
                }
            })(i);
        }

Execute function format immediately

Synchronization task: for loop

Asynchronous task: timer function, event function, ajax, triggered to execute

5.5 Debugging closures in chrome

  1. Open your browser and press F12 to launch the chrome debugging tool.

  2. Set breakpoints.

  3. Find the Scope option (what Scope scope means).

  4. When we refresh the page, we enter breakpoint debugging with two parameters (global global scope, local local local scope) inside the Scope.

  5. When fn2() is executed, there will be an additional Closure parameter inside the Scope, indicating that a closure has been generated.

6. Recursion

6.1 What is recursion

If a function can call itself internally, it is a recursive function.

        // Recursive function: a function calls itself within itself, and this function is a recursive function
        var num = 1;
        function fn() {
            console.log('I want to print 6 sentences');
            if (num == 6) {
                return; // Exit criteria must be added to recursion
            }
            num++;
            fn();
        }
        fn();
  • Recursive functions work as well as looping

  • To prevent stack overflow errors, an exit condition return must be added to recursion

6.2 Shallow and Deep Copies

  • shallow copy
        // Shallow copies are only one level of copy, and deeper object-level, copy-only reference addresses. Alteration
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            }
        };
        var o = {};
        // for (var k in obj) {
        //     // K is the property name obj[k] property value
        //     o[k] = obj[k];
        // }
        // console.log(o);
        // o.msg.age = 20;
        // console.log(obj);

        console.log('--------------');
		// es6 grammatical sugar
        Object.assign(o, obj);
        console.log(o);
        o.msg.age = 20;
        console.log(obj);
  • deep copy
        // Deep copies are multiplayer, and data at each level is copied. Unchanged
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            },
            color: ['pink', 'red']
        };
        var o = {};
        // Encapsulation function 
        function deepCopy(newobj, oldobj) {
            for (var k in oldobj) {
                // Judging which data type our attribute values belong to
                // 1. Get the attribute value oldobj[k]
                var item = oldobj[k];
                // 2. Determine if this value is an array or an object, so write the array first
                if (item instanceof Array) {
                    newobj[k] = [];
                    deepCopy(newobj[k], item)
                } else if (item instanceof Object) {
                    // 3. Determine if this value is an object
                    newobj[k] = {};
                    deepCopy(newobj[k], item)
                } else {
                    // 4. Is a simple data type
                    newobj[k] = item;
                }
            }
        }
        deepCopy(o, obj);
        console.log(o);

        var arr = [];
        console.log(arr instanceof Object);
        o.msg.age = 20;    //A Change
        console.log(obj); //Unchanged
  • summary
  1. Shallow copies are only one level of copy, and deeper object-level, copy-only references.
  2. Deep copies are multiplayer, and data at each level is copied.
  3. Object.assign(target,... sources) es6 new method can be shallowly copied

regular expression

Regular expressions are patterns used to match combinations of characters in strings. Regular expressions are also objects in JavaScript. They are commonly used for matching (limiting input), replacing (sensitive words), and extracting (specific parts).

        // Use of regular expressions in js

        // 1. Create regular expressions using RegExp objects
        var regexp = new RegExp(/123/);
        console.log(regexp);

        // 2. Create regular expressions using literal quantities
        var rg = /123/;

        // 3. The test method is used to detect whether a string meets the specifications of a regular expression
        console.log(rg.test(123));
        console.log(rg.test('abc'));

1. Special Characters

1.1 Boundary Character

        // Boundary Character ^Beginning$Ending 
        var rg = /abc/; // Regular expressions do not require quotation marks whether they are numeric or string
        // /abc/Returns true as long as the string contains ABC
        console.log(rg.test('abc'));
        console.log(rg.test('abcd'));
        console.log(rg.test('aabcd'));
        console.log('---------------------------');
        var reg = /^abc/; // Beginning of abc
        console.log(reg.test('abc')); // true
        console.log(reg.test('abcd')); // true
        console.log(reg.test('aabcd')); // false
        console.log('---------------------------');
        var reg1 = /^abc$/; // The ^$exact match requirement must be an abc string to conform to the specification
        console.log(reg1.test('abc')); // true
        console.log(reg1.test('abcd')); // false
        console.log(reg1.test('aabcd')); // false
        console.log(reg1.test('abcabc')); // false

1.2 Character Class

        //Var RG =/abc/; As long as it contains ABC 
        // Character class: [] means that there is a list of characters to choose from, as long as one of them is matched
        var rg = /[abc]/; // Returns true as long as it contains a or b or c
        console.log(rg.test('andy'));
        console.log(rg.test('baby'));
        console.log(rg.test('color'));
        console.log(rg.test('red'));
        var rg1 = /^[abc]$/; // Choose one of the three letters a or b or c to return true
        console.log(rg1.test('aa'));
        console.log(rg1.test('a'));
        console.log(rg1.test('b'));
        console.log(rg1.test('c'));
        console.log(rg1.test('abc'));
        console.log('------------------');
        var reg = /^[a-z]$/; // 26 English letters Any letter returns true - denotes the range a to z  
        console.log(reg.test('a'));
        console.log(reg.test('z'));
        console.log(reg.test(1));
        console.log(reg.test('A'));
        // Character Combination
        var reg1 = /^[a-zA-Z0-9_-]$/; // 26 English letters (both upper and lower case) Any one returns true  
        console.log(reg1.test('a'));
        console.log(reg1.test('B'));
        console.log(reg1.test(8));
        console.log(reg1.test('-'));
        console.log(reg1.test('_'));
        console.log(reg1.test('!'));
        console.log('----------------');
        // If there is a ^ in the middle bracket, don't confuse it with our boundary character ^
        var reg2 = /^[^a-zA-Z0-9_-]$/;
        console.log(reg2.test('a'));
        console.log(reg2.test('B'));
        console.log(reg2.test(8));
        console.log(reg2.test('-'));
        console.log(reg2.test('_'));
        console.log(reg2.test('!'));

1.3 Quantifier

        // Quantifier: Used to set the number of times a pattern occurs
        // Simple understanding: is how many times to repeat the following a character
        // var reg = /^a$/;

        //  *Equivalent to >= 0 can occur 0 or many times 
        // var reg = /^a*$/;
        // console.log(reg.test('')); // true
        // console.log(reg.test('a')); // true
        // console.log(reg.test('aaaa')); // true

        //  +Equivalent >= 1 can occur once or many times
        // var reg = /^a+$/;
        // console.log(reg.test('')); // false
        // console.log(reg.test('a')); // true
        // console.log(reg.test('aaaa')); // true

        //  What? Equivalent to 1 || 0
        // var reg = /^a?$/;
        // Console. Log(reg.test(');// 0 times true
        // Console. Log(reg.test('a'); // true once
        // console.log(reg.test('aaaa')); // false

        //  {3} is repeated three times
        // var reg = /^a{3}$/;
        // console.log(reg.test('')); // false
        // console.log(reg.test('a')); // false
        // console.log(reg.test('aaaa')); // false
        // console.log(reg.test('aaa')); // true
        //  {3,} greater than or equal to 3
        var reg = /^a{3,}$/;
        console.log(reg.test('')); // false
        console.log(reg.test('a')); // false
        console.log(reg.test('aaaa')); // true
        console.log(reg.test('aaa')); // true
        //  {3,16} greater than or equal to 3 and less than or equal to 16 Note that there are no spaces in between
        var reg = /^a{3,6}$/;
        console.log(reg.test('')); // false
        console.log(reg.test('a')); // false
        console.log(reg.test('aaaa')); // true
        console.log(reg.test('aaa')); // true
        console.log(reg.test('aaaaaaa')); // false

1.4 brackets

        // A collection of bracketed characters. Match any character in square brackets. 
        // var reg = /^[abc]$/;
        // A or B or C can be a ||b ||c

        // Brace quantifier. Repeat count inside
        // var reg = /^abc{3}$/; // It just lets c repeat abccc three times
        // console.log(reg.test('abc')); // f
        // console.log(reg.test('abcabcabc')); // f
        // console.log(reg.test('abccc')); // t

        // Parentheses denote priority
        var reg = /^(abc){3}$/; // It lets abc repeat three times
        console.log(reg.test('abc')); // f
        console.log(reg.test('abcabcabc')); // t
        console.log(reg.test('abccc')); // f

Online Testing Rookie Tools

1.5 Predefined Classes

Predefined classes are shortcuts to some common patterns

Predefined classExplain
\dMatch any number between 0-9, equivalent to [0-9]
\DMatches all characters other than 0-9, equivalent to [^0-9]
\wMatch any letter, number, and underscore, equivalent to [A-Za-z0-9_]
\WCharacters other than all letters, numbers, and underscores, equivalent to [^A-Za-z0-9_]
\sMatch spaces (including line breaks, tabs, space characters, etc.), equivalent to [\t\r\n\v\f]
\SMatches a character that is not a space, equivalent to [^\t\r\n\v\f]

2. Replace

2.1 replace replacement

The replace() method implements a substitution string operation, where the replacement parameter is a string or a regular expression, and the return value is a new string that has been replaced, but only the first string that meets the criteria will be replaced.

        // Replace replace
        // Var STR ='andy and red';
        // // var newStr = str.replace('andy', 'baby');
        // var newStr = str.replace(/andy/, 'baby');
        // console.log(newStr);
        var text = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.onclick = function() {
            div.innerHTML = text.value.replace(/Passion|gay/g, '**');
        }

2.2 Regular Expression Parameters

/expression/{switch}

There are three values for which switch (also known as modifier) matches in a pattern:

  • g: global matching
  • i: ignore case
  • gi: global match + ignore case

ES6

1. New syntax for ES6

1.1 let keyword

  • let-declared variables are valid only at the block level
 if (true) { 
     let a = 10;
 }
 console.log(a) // a is not defined
  • There is no variable promotion (you can use it before es6)
 console.log(a); // a is not defined 
 let a = 20;
  • Transient Dead Zone (Variables declared with let at the block level are bound within the block level scope and are not affected by external variables)
 var tmp = 123;
 if (true) { 
     tmp = 'abc';
     let tmp; 
 } 
		var num = 10
		if (true) {
			console.log(num); 
            //Error using num in this block-level scope without declaring it is not related to external num
			let num = 20;
		}
  • Prevent loop variables from becoming global
 for (let i = 0; i < 2; i++) {}
 console.log(i);

Classic interview questions

  • Variable i is global and the output of the function is global i
 var arr = [];
 for (var i = 0; i < 2; i++) {
     arr[i] = function () { // Assigning function() to arr[i], does not execute function()
         console.log(i); // Function internal undefined i lookup up level according to scope chain
         // The value function of global variable i executes with the output value 2 of i that does not satisfy the loop condition after the loop ends
     }
 }
 // i=2 for Loop End Starts executing the following statement
 arr[0]();
 arr[1]();

Change var to let

  • Each loop produces a block-level scope, with variables in each block-level scope being different (independent of each other), and the output of the function when it executes is the i value in the scope of its parent (the block-level scope generated by the loop).
 let arr = [];
 for (let i = 0; i < 2; i++) {
     arr[i] = function () {
         console.log(i); 
     }
 }
 arr[0]();
 arr[1]();

1.2 const keyword

Role: Declares a constant, which is a variable whose value (memory address) cannot be changed.

  • Has Block Scope
 if (true) { 
     const a = 10;
 }
 console.log(a) // a is not defined
  • A constant must be assigned when it is declared
 const PI; // Missing initializer in const declaration
  • After a constant is assigned, the value cannot be modified
 const PI = 3.14;
 PI = 100; // Assignment to constant variable. 
 // Basic data type values are not changeable
 const ary = [100, 200];
 ary[0] = 'a';
 ary[1] = 'b';
 console.log(ary); // ['a', 'b']; 
 ary = ['a', 'b']; // Assignment to constant variable.
 // Values inside data structures of complex data types can be changed but cannot be reassigned (memory addresses corresponding to constant values cannot be changed)

Differences between 1.3 let, const, var

  1. Variables declared with var are scoped within the function in which the statement resides and exhibit variable promotion.
  2. A variable declared with a let whose domain is the block of code in which the statement resides does not have a variable promotion.
  3. const is declared as a constant and its value cannot be modified in subsequent code.
varletconst
Functional ScopeBlock-level ScopeBlock-level Scope
Variable PromotionNo Variable PromotionNo Variable Promotion
Value can be changedValue can be changedValue is not changeable

1.4 Deconstruction assignment

ES6 allows you to extract values from arrays and assign values to variables by location. Objects can also be deconstructed.

Array Deconstruction

		// Array deconstruction allows us to extract values from an array in a one-to-one relationship and assign values to variables
		let ary = [1,2,3];
		let [a, b, c, d, e] = ary; // Unfined if there is no corresponding value variable
		console.log(a)
		console.log(b)
		console.log(c)
		console.log(d)
		console.log(e)

Object Deconstruction

		// Object deconstruction allows us to successfully assign values of object attributes to variables using the name of the variable to match the attribute matching of the object
		
		let person = {name: 'lisi', age: 30, sex: 'male'};
		// Let {name, age, sex} = person; // Variable Matching Properties
		// console.log(name)
		// console.log(age)
		// console.log(sex)
		
		let {name: myName} = person; // myName belongs to an alias
		// Assign the value corresponding to the name attribute to the myName variable
		console.log(myName)

1.5 Arrow Function

New way to define functions in ES6.

		// Arrow functions are used to simplify the function definition syntax
		 const fn = () => {
		 	console.log(123)
		 }
		 fn();

There is only one sentence of code in the body of the function, and the result of executing the code is the return value, which can be omitted from braces

		// In an arrow function, if there is only one sentence of code in the body of the function and the result of the execution of the code is the return value of the function, the body curly braces may be omitted
		 const sum = (n1, n2) => n1 + n2;	 
		 const result = sum(10, 20);
		 console.log(result)
		
		// In an arrow function, parentheses outside a parameter can also be omitted if the parameter has only one parameter
		 const fn = v => {
		 	alert(v);
		 }
		   fn(20)
		
		// Arrow function does not bind this Arrow function does not have its own this keyword
	   // If the keyword this this this is used in an arrow function, it will point to this in the location defined by the arrow function		
		function fn () {
			console.log(this);
			return () => {
				console.log(this)
			}
		}
		const obj = {name: 'zhangsan'};
		const resFn = fn.call(obj);
		resFn();

Arrow Function Interview Question

		var age = 100; // Add an age attribute under window

		// obj is an object and cannot produce a scope. The arrow function is actually defined in a global scope with this pointing to window 
		var obj = {
			age: 20,
			say: () => {
				alert(this.age)
			}
		}
        
		obj.say();

1.6 Remaining parameters

The remaining parameter syntax allows us to represent an indefinite number of parameters as an array.

		// const sum = (...args) => {
		// 	let total = 0;
		// 	args.forEach(item => total += item);
		// 	return total;
		// };

		// console.log(sum(10, 20));
		// console.log(sum(10, 20, 30));		

		let ary1 = ['Zhang San' , 'Li Si', 'King Five'];
		let [s1, ...s2] = ary1;
		console.log(s1) // Zhang San
		console.log(s2) // Array ['Li Si','Wang Wu']

2. Built-in Object Extensions for ES6

2.1 Array's Extension Method

Extension Operator (Expansion Syntax)

		// Extension operators split arrays into comma-separated parameter sequences
		// let ary = ["a", "b", "c"];
		// ...ary // "a", "b", "c"
		// console.log(...ary)
		// console.log("a", "b", "c")
		
		// Extension operators can be used for combinatorial union of numbers
		// let ary1 = [1, 2, 3];
		// let ary2 = [4, 5, 6];
		// // ...ary1 // 1, 2, 3
		// // ...ary1 // 4, 5, 6
		// let ary3 = [...ary1, ...ary2];
		// console.log(ary3)

		// Second method of merging arrays
		// let ary1 = [1, 2, 3];
		// let ary2 = [4, 5, 6];
		// ary1.push(...ary2);
		// console.log(ary1)
		
		// Pseudo-arrays can be converted to real arrays using extension operators
		var oDivs = document.getElementsByTagName('div');
		console.log(oDivs)
		var ary = [...oDivs];
		ary.push('a');
		console.log(ary);

Constructor method: Array.from()

Converts an array of classes or traversable objects into a real array, which also accepts the second parameter and acts like an array's map method, handling each element and putting the processed value into the returned array.

		// var arrayLike = {
		// 	"0": "Zhang San",
		// 	"1": "Li Si",
		// 	"2": "Wang Wu",
		// 	"length": 3
		// }
		// var ary = Array.from(arrayLike);
		// console.log(ary)
		
		var arrayLike = {
			"0": "1",
			"1": "2",
			"length": 2
		}

		var ary = Array.from(arrayLike, item => item * 2)
		console.log(ary)

Instance method: find()

Used to find the first eligible array member, if no undefined return is found

		var ary = [{
			id: 1,
			name: 'Zhang San'
		}, {
			id: 2,
			name: 'Li Si'
		}];
		let target = ary.find(item => item.id == 3);
		console.log(target)

Instance method: findIndex()

Used to find the position of the first eligible array member, if no Return-1 is found

		let ary = [10, 20, 50];
		let index = ary.findIndex(item => item > 15);
		console.log(index)

Instance method: include ()

Returns a Boolean value indicating whether an array contains a given value.

		let ary = ["a", "b", "c"];
		let result = ary.includes('a')
		console.log(result)
		result = ary.includes('e')
		console.log(result)

Extension Method for 2.2 String

Template String

ES6's new way of creating strings, defined with inverted Quotes

        // Variables can be parsed in the template string.
        let name = `Zhang San`;
        let sayHello = `Hello, My name is ${name}`;
        console.log(sayHello);

        // Line breaks are possible in Template Strings
        let result = {
            name: "zhangsan",
            age: 20
        };
        let html = `
		<div>
		<span>${result.name}</span>
		<span>${result.age}</span>
		</div>
		`;
        console.log(html);

        // Functions can be called in the template string.
        const fn = () => {
            return 'I am fn function'
        }
        let html = `I am a template string ${fn()}`;
        console.log(html)

Instance methods: startsWith() and endsWith()

  • startsWith(): Returns a Boolean value indicating whether the parameter string is at the head of the original string
  • endsWith(): Returns a Boolean value indicating whether the parameter string is at the end of the original string
		let str = 'Hello ECMAScript 2015';
		let r1 = str.startsWith('Hello'); // t
		console.log(r1);
		let r2 = str.endsWith('2016'); // f
		console.log(r2)

Instance method: repeat()

The repeat method means that the original string is repeated n times and a new string is returned.

'x'.repeat(3)      // "xxx" 
'hello'.repeat(2)  // "hellohello"

2.3 Set Data Structure

ES6 provides a new data structure Set. It is similar to an array, but members have unique values and no duplicate values.

Set itself is a constructor used to generate Set data structures.

const s = new Set();

The Set function can accept an array as an argument to initialize.

const set = new Set([1, 2, 3, 4, 4]);

Instance Method

  • add(value): Add a value and return the Set structure itself
  • delete(value): Deletes a value and returns a Boolean value indicating whether the deletion was successful
  • has(value): Returns a Boolean value indicating whether the value is a member of the Set
  • clear(): Clear all members, no return value
        const s1 = new Set();
        console.log(s1.size)

        const s2 = new Set(["a", "b"]);
        console.log(s2.size)

        const s3 = new Set(["a", "a", "b", "b"]); // Array Weighting
        console.log(s3.size)
        const ary = [...s3];
        console.log(ary)

        const s4 = new Set();
        // Add values to the set structure using the add method
        s4.add('a').add('b');
        console.log(s4.size)

        // The method used to delete values from the set structure is delete
        const r1 = s4.delete('c');
        console.log(s4.size)
        console.log(r1);

        // Determine if a value is a member of the set data structure using has
        const r2 = s4.has('d');
        console.log(r2)

        // Empty values in set data structure using clear method
        s4.clear();
        console.log(s4.size);

        // Traverse the set data structure to get values from it
        const s5 = new Set(['a', 'b', 'c']);
        s5.forEach(value => {
            console.log(value)
        })

Tags: Front-end Javascript ECMAScript

Posted by Sakesaru on Sun, 17 Apr 2022 01:48:19 +0930