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
- There is no variable promotion for classes in ES6, so classes must be defined before objects can be instantiated through classes
- Common attributes and methods within a class must be used with this
- 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:
- Object Literal
- new Object()
- 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:
- Constructors are used to create a class of objects whose initial letters are capitalized
- 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
- When accessing the properties (including methods) of an object, first find out if the object itself has the property.
- If not, look for its prototype (that is, the prototype object that u proto u points to).
- Find the prototype of the prototype object (the prototype object of the Object) if you haven't already done so.
- And so on until Object is found (null).
- _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:
- Extract the methods shared by the subclass so that the prototype prototype object of the subclass = the new parent class ()
- 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
- class is essentially a function.
- All methods of the class are defined on the prototype property of the class.
- Instances of class creation with u proto u The prototype prototype object pointing to the class.
- 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.
- The ES6 class is actually grammatical sugar.
- 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
- 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
- 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
-
Custom functions (named functions)
function fn() {};
-
Function expression (anonymous function)
var fun = function() {};
-
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
-
General function
function fn() {}; fn(); fn.call();
-
Method of object
var o = { sayHi:function(){ } } o.sayHi();
-
Constructor
function Star(){}; new Star();
-
Bind Event Function
btn.onclick = function(){}; //Click the button to invoke
-
Timer Functions
setInterval(function(){},1000); //Timer automatically called once a second
-
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.
-
The normal function this points to window
function fn() {}; fn(); fn.call(); window.fn() //Complete Writing
-
Object's method this points to the object to which the method belongs o
var o = { sayHi:function(){ } } o.sayHi();
-
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();
-
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
-
The timer function this also points to window
setInterval(function(){},1000); //Timer automatically called once a second
-
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
- Call function
- Changing the this direction within a function
- 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:
- Call and apply call functions, but bind does not call functions
- call and apply pass different parameters, apply parameters are arrays
Main application scenarios
- call inheritance
- apply is often associated with arrays, such as minimizing the maximum of an array with the aid of a mathematical object
- 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.
-
Global variables can be used inside a function.
-
Local variables cannot be used outside a function.
-
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
-
Open your browser and press F12 to launch the chrome debugging tool.
-
Set breakpoints.
-
Find the Scope option (what Scope scope means).
-
When we refresh the page, we enter breakpoint debugging with two parameters (global global scope, local local local scope) inside the Scope.
-
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
- Shallow copies are only one level of copy, and deeper object-level, copy-only references.
- Deep copies are multiplayer, and data at each level is copied.
- 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 class | Explain |
---|---|
\d | Match any number between 0-9, equivalent to [0-9] |
\D | Matches all characters other than 0-9, equivalent to [^0-9] |
\w | Match any letter, number, and underscore, equivalent to [A-Za-z0-9_] |
\W | Characters other than all letters, numbers, and underscores, equivalent to [^A-Za-z0-9_] |
\s | Match spaces (including line breaks, tabs, space characters, etc.), equivalent to [\t\r\n\v\f] |
\S | Matches 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
- Variables declared with var are scoped within the function in which the statement resides and exhibit variable promotion.
- A variable declared with a let whose domain is the block of code in which the statement resides does not have a variable promotion.
- const is declared as a constant and its value cannot be modified in subsequent code.
var | let | const |
---|---|---|
Functional Scope | Block-level Scope | Block-level Scope |
Variable Promotion | No Variable Promotion | No Variable Promotion |
Value can be changed | Value can be changed | Value 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) })