Introduction to the
Hello, everyone, I am Six six. It took a week to finally write this summary of the core concepts of JS. The creative process is also to fill in the gaps, I hope you can also have a harvest. Give a thumbs-up to the author if you like, it’s not easy to create.
A series of forecast
2. The only way to advance the front end (2) : the front end will be 20 handwriting and algorithm 3. The way to the front end (three) : the front end will be Vue 7 big handwritten source
note
- If there are mistakes, please actively point out, to avoid misleading others. (This is the first time to write so many words, there will be mistakes)
- If you have anything to add, please let me know and I will actively add it.
- I am also a white, I hope to learn and progress with you. So if you spray me, I’ll spray back.
- If I accidentally introduce a snippet from someone else’s article, point it out and I’ll add it in place.
A series of
Directory:
Js operating environment 2. Js data type 3. Js type conversion 4. Scopes and scope chains 6. closures 7. stereotypes and prototype objects 8.this points to problem 9. Js data storage and parameter transfer 11. Deep copy and shallow copy (write a deep copy by hand) 12. Higher-order functions and Currization 13. Ajax 14.DOM 15.BOM 16. Wrap objects 17. Encapsulate polymorphisms 18. Single threads and event loops 20.promise 21.es6 modular
1. Js running environment
As a scripting language, JS runs in the browser, which is the runtime environment of JS. For many popular browser vendors, their kernels are different. Browser kernels are divided into two types: rendering engines and JS engines.
Rendering engine: responsible for rendering web content.
Js engine: explain Js script, Js interaction effect.
1.1 Common Cores:
1.2 Now that we have a JS file, how does the browser execute it?
First of all, our JS file is rendered in HTML as a SCirpt tag element. The browser parses the tag according to the HTML file, and when it reaches the SCirpt tag, it will stop the HTML parsing, block, and start downloading the JS file and executing it. In the process of executing, if it is the first JS file, the browser will trigger the first rendering (as for why, do the experiment by yourself, you can leave a message if you don’t understand). Therefore, there is a problem that js files greatly hinder the parsing and rendering of HTML pages, so two properties async and defer are introduced (for the first screen optimization is greatly improved, and should be used with caution).
Async: Start another thread to download the JS file. (This is when blocking occurs)
Defer: Start another thread to download the JS file and wait until the page has finished loading. (Not blocking at all)
2. Js data type
Basic data types:
String: A sequence of 16-bit Unicode characters, represented by single or double quotation marks
Number: indicates integer and floating point values in IEEE754 format
Boolean: Has two literals, true and false. Case sensitive
Null: A data type with a single value. The value is null. Represents an empty object pointer, but typeof operations return an object. We typically initialize variables that will be used to hold objects to NULL.
Undefined: This type has only one value, which is undefined when a variable is declared and not assigned.
Symbol: unique value.
Reference data types:
Object: A collection of data and functions, stored in unordered key-value pairs. It can be created using the new operator and the create object constructor. Common object types are array,date,function, etc.
Classic interview questions:
Why doesn’t 0.1+0.2 equal 0.3?
0.1 and 0.2 will loop indefinitely after being converted to binary, truncating the extra bits due to the standard bit limit. This will already result in a loss of precision. The binary truncated by the floating-point decimal limit after being added will become 0.30000000000000004 when converted to decimal. Data type detection method:
1.typeof
Typeof detects that NULL is an object
Typeof detects a function when a function returns
Typeof detects that all other objects return Object
2. Instanceof (handwritten in the next section)
Instanceof checks the result as true as long as it is on the current instance’s prototype chain, so the result may not be correct in the class’s prototype inheritance. And instanceof must be followed by an object. Cannot detect base types
3. The constructor:
Each constructor’s prototype object has a constructor property that points to the constructor itself, and since we can modify this property manually, the results are not very accurate. Cannot detect NULL and undefined
4. Object. The prototype. ToString. Call (best)
Call the toString() method on the Object prototype and change the this pointer with call. It returns a string
Js type conversion
JavaScript, as a weakly typed language, essentially means that a variable can be assigned different data types. The code is neat and flexible, but there are a lot of holes in it.
JavaScript is also a dynamically typed language, allowing you to change the structure of its variables at runtime.
So js variables can do any type conversion, there are two ways, display conversion and hermit conversion.
But there are only three types that can be converted: to Number,to String, and to Boolean.
Call when a basic type is converted to: Number(),String(), Boolean()
Only ‘0’ null undefined NaN false Converts Boolean to false, all others to true
When referencing type conversions, it gets a little more complicated. For example :(all object conversions Boolean is true)
Let obj={value:' hello ', num:2, toString:function(){return this.value}, valueOf:function(){return this.num}, } console.log(obj+' tomorrow ') //2 console.log(obj+1) // 3 console.log(String(obj)) // HelloCopy the code
When an object is cast:
1. Call valueOf first, return if the result is the original value, if not the next step
2. Next, call toString. If the result is the original value, return it.
Special circumstances:
When converting toString using a display type, toString is called first and valueOf is called second
Display type conversion:
Number() / parseFloat() / parseInt()/String() / toString()/Boolean()
Hermit type conversion:
+ – = =! > < = < = > =
3.1 classic interview questions :(can answer really very powerful, leave a name let me pay attention to worship)
1 + '1' true + 0 {}+[] 4 + {} 4 + [1] 'a' + + 'b' console.log ( [] == 0 ) console.log ( ! [] == 0 ) console.log ( [] == ! [] ) console.log ( [] == [] ) console.log({} == ! {}) console.log({} == {})Copy the code
You know when you're wrong, but you forget when you're done. Answer: '11' 1 0 "4[object object]" "41" "aNaNCopy the code
4. Js traversal
4.1 Object Traversal:
1. For in: self and inheritance attribute, enumerable, without Symbol
2.Object. Keys (OBj): enumerable, without Symbol, itself
3.Object. Values (obj) : enumerable, does not include Symbol, itself
4. Object. GetOwnPropertyNames (obj) : its all properties, excluding Symbol
5.Reflect.ownKeys(obj): All of its own properties
4.2 Array Traversal:
ForEach, map, filter, every, some, reduce, etc.
4.3 String Traversal:
for in
4.4 Set Data Structure:
Set.prototype.keys(): iterator that returns key names
Set.prototype.values() : iterator that returns key values
Set.prototype.entries() : Returns a traverser for key and value pairs
Set.prototype.foreach () : callback to iterate over each member
4.5 Map Data Structure:
Map.prototype.keys(): iterator that returns key names
Map.prototype.values() : iterator that returns key values
Map.prototype.entries() : Returns a traverser for key and value pairs
Map.prototype.foreach () : callback function iterates through each member
5. Scope and scope chain
5.1 scope
Javascript uses static scopes, also known as lexical scopes, which means that scopes are created at definition time, not at runtime. This sentence is difficult for beginners to understand, take a look at the following example:
Let a=1 function aa(){console.log(a)} function bb(){let a=2 aa()}Copy the code
Whether very counterintuitive, you see, aa calls in bb, aa function does not have a variable, it should be to call it using the field to look, just find a equal to 2. The idea is perfect, but the static scope adopted by the JS authors, no matter how you run it, is already generated when you define it.
So what is scope?
A region or set of variables and functions that can be accessed efficiently. A scope determines resource accessibility between blocks of code.
A scope is a separate space that protects variables from leaks and also acts as isolation. Variables in each scope can be named the same without interference. Just like a house, each house is independent, which is the scope.
Scope is divided into global scope, function scope and block scope. The global scope can be accessed anywhere, such as window,Math, and other global objects. A function scope is a function’s internal variables and methods that cannot be accessed outside the function. Block-level scope means that a variable declaration is not accessible outside the code segment, such as let,const.
5.2 Scope chain
Now that we know the scope, what is a scope chain?
Represents a collection of variables that a scope can access. The function as an object has a [[scope]] property that represents this collection. A few more concept words:
AO: Active Variable (VO)
VO: Variable object (VO)
Execution context: The environment in which code is run, including a global context and a functional context.
Function a() {function b() {var b = 234; function b() {var b = 234; } var a = 123; b(); } var gloab = 100; a();Copy the code
Step 1: a function definition
As can be seen from the figure above, when a function is defined, the scope of the attribute [[scope]] of a function Object points to its scope chain. At this time, the first item of its scope chain points to the GO(Global Object) Global Object. We can see that there are five properties on the Global Object at this time. They are this, Window, document, a and glob.
Step 2: function A is executed
When function A is executed, the first entry in the scope chain of function A’s scope Object [[scope]] points to an Activation Object (AO). The AO Object has four properties: This, arguments, A, and B. The second item refers to GO(Global Object), which still has five attributes: This, Window, Document, A and GOLb.
Step 3: B function definition! When the function B is defined, the first entry in the scope chain of the function b Object [[scope]] points to an Activation Object (AO). The AO Object has four properties: This, arguments, A, and B. The second item refers to GO(Global Object), which still has five attributes: This, Window, Document, A and GOLb.
Step 4: b function executionWhen b is executed, the first entry in the scope chain of the b function Object [[scope]] points to an Activation Object (AO). The AO Object has three properties: This, arguments, and B. The first item points to an Activation Object (AO). The AO Object has four properties: This, Arguments, A, and B. The second item refers to GO(Global Object), which still has five attributes: This, Window, Document, A and GOLb. This is the result of executing the code above.
6. Closure
Source: https://github.com/mqyqingfeng/Blog/issues/9Copy the code
A programmer who doesn’t know closures is a bad programmer.
The official definition of a closure:
MDN: Closures are functions that have access to free variables.
Closures can be generated when another function can be defined (nested) within a function if the inner function references a variable of the outer function. Closures can be used to create associations between a function and a set of “private” variables. These private variables maintain their persistence over the course of multiple calls to a given function.
Me: Closures are generated when one scope can access variables in another scope. The analogy is that the scope is like a house, and the closure is like a door.
What is a free variable?
A free variable is a variable that is used in a function but is neither a function parameter nor a local variable of the function.
Closures = functions + free variables that functions can access.
Technically speaking, all JavaScript functions are closures.
var a = 1;
function foo() {
console.log(a);
}
foo()
Copy the code
Function foo can access variable a, but a is neither a local variable nor an argument to function foo, so a is a free variable.
So foo + foo’s free variable a forms a closure…
When we look at ECMAScript, closures refer to:
1. From a theoretical perspective: all functions. Because they both store the data of the upper context at the time of creation. This is true even for simple global variables, since accessing a global variable in a function is equivalent to accessing a free variable, using the outermost scope.
2. As a practical matter: the following functions are closures:
- It persists even if the context in which it was created has been destroyed (for example, an inner function returns from a parent function)
- Free variables are referenced in the code
Let’s start with a practical demonstration :(again, examples from JavaScript’s definitive guide)
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f; } var foo = checkscope(); foo(); Output "local scope"Copy the code
The scope chain is defined when the function is defined, so let’s look at the [[scope]] property used to define f functions:
[
AO:{
scope:"local scope",
f:function
},
global:{
scope :"local scope",
checkscope:function
}
]
Copy the code
F [[scope]] property when executed:
[ AO:{ arguments:[], this:window }, AO:{ scope:"local scope", f:function }, global:{ scope :"local scope", Checkscope :function}] checkscope:function}Copy the code
Classic interview questions:
var data = []; for (var i = 0; i < 3; i++) { data[i] = function () { console.log(i); }; } data[0](); data[1](); data[2](); The answer is both 3's, and let's analyze why:Copy the code
Before data[0] is executed, the VO of the global context is:
globalContext = { VO: { data: [...] , i: 3 } }Copy the code
When data[0] is executed, the scope chain of data[0] is:
data[0]Context = {
Scope: [AO, globalContext.VO]
}
Copy the code
The AO of data[0]Context does not have an I value, so it looks up globalContext.VO, where I is 3, so it prints 3
7. Prototypes and prototype objects
Not to mention, if you can recite the following picture, it is very simple to understand.
Let me first talk about my understanding:
Javascript everything is an object, and each object has a __proto__ attribute that points to the prototype object of the constructor that created it.
Each function has a prototype object, prototype, which is inherited when an object is created using new.
function A(){}
var a=new A()
a.__proto__===A.prototype
Copy the code
Now the question is, who created the constructor A, and who else created the object a.prototype?
At this time we need to know js two top-level functions, Function,Object
All functions are created by Function
A.__proto__===Function.prototype
Copy the code
I just said that all functions are created by Function, including itself. That is, Function creates itself:
Function.__proto__===Function.prototype
Copy the code
All fish belong to the cat hahahahaha
Object.__proto__===Function.prototype
Copy the code
All objects are created by the Object constructor:
A.prototype.__proto__===Object.prototype
Copy the code
Object. Prototype is the prototype of the prototype Object. In the end there will be nothing.
Object.prototype.__proto__===null
Copy the code
Prototype chain (an access mechanism) :
1. When accessing a member of an object, the system checks whether the member exists in the object
2. If there is none in the current object, look in the constructor’s prototype object
3. If you don’t find the prototype object, look for the prototype object’s prototype
4. Until the prototype of Object is null
8. This refers to the problem
8.1 Global Environment Common function calls, common objects
const obj={a:this}
obj.this===window //true
function fn(){
console.log(this) //window
}
Copy the code
8.2 Constructors
function a() {
console.log(this)
}
const obj = new a() // a{}
a() // 'window'
Copy the code
The object coming out of new, this refers to the object coming out of new. Executed as a normal function, this refers to the window.
8.3 Object Methods
const obj = {
x: 0,
foo: function () {
console.log(this)
}
}
obj.foo() // obj
const a = obj.foo
a() //window
Copy the code
As an object method, this refers to this object. (The new object is bound to this of the function call.) Once a variable refers directly to the method, this is the window.
A special case
If you execute a function inside a method, this points to the window.
const obj = {
x: 0,
foo: function () {
console.log(this) // obj
function foo1() {
console.log(this) //window
}
foo1()
}
}
obj.foo()
Copy the code
8.4 Constructor prototype property
Function Fn() {this.a = 10 let a = 100} Fn.prototype. Fn = function () {console.log(this.a) // 10 obj = new Fn() obj.fn()Copy the code
The this of the stereotype definition method points to the instance object. After all, it’s called through an object.
8.5 the call, the apply, bind
const obj = {
x: 10
}
function fn() {
console.log(this)
}
fn.call(obj) //obj
fn.apply(obj) //obj
fn.bind(obj)() //obj
Copy the code
This refers to the object passed in.
8.6 the DOM event
Document.getelementbyid ('app').adDeventListener ('click', function () {console.log(this) // the object whose id is app})Copy the code
Object that points to the bound event.
8.7 Arrow Function
Obj = {a: 10, c: the function () {b = () = > {the console. The log (this) / / to obj} b ()}} obj. C ()Copy the code
The function defined in the method should point to the window, but the arrow function does not have its own this, so it points to this in the upper scope.
Document.getelementbyid ('app').addeventListener ('click', () => {console.log(this) // change the arrow function to point to the window instead of the trigger object})Copy the code
8.8 Binding Mode:
Hermit binding:
Who calls the method, who this points to.
According to the binding
call,bind,apply
The new binding
Priority issues:
New > Show Binding > Implicit binding
Classic interview questions:
It’s easy for the brass to find out.
9. Inheritance
- Prototype chain inheritance
- Constructor inheritance
- Combination of inheritance
- Parasitic combinatorial inheritance
- Extends inheritance
9.1 Inheritance of prototype Chain:
function Animal() { this.name = 'cat' this.msg = { age: 9 } } Animal.prototype.greet = function () { console.log('hehe') } function Dog() { this.name = 'dog' } Dog.prototype = New Animal() // Core 1 const a = new Dog() a.smg.age = '99' const b = new Animal()Copy the code
Disadvantages: Multiple instances can tamper with operations on reference types
9.2 Constructor Inheritance:
function Animal() { this.name = 'cat' this.msg = { age: 1}} animal.prototype. Greet = function () {console.log('hehe')} function Dog() {animal.call (this)} const a=new Dog()Copy the code
Disadvantages:
- Only instance properties and methods of the parent class can be inherited, not stereotype properties/methods.
- Performance is poor, and each subclass will have a copy of the parent instance.
9.3 Combination Inheritance:
It’s a combination of the two
function Animal() { this.name = 'cat' this.msg = { age: 1}} animal.call (this) {animal.call (this); // animal.call (this); Dog. Prototype =new Animal() // Const a=new Dog()Copy the code
9.4 Original type inheritance
Assign an object directly to the prototype of the empty object constructor using an empty object as a mediator.
- Function reuse is not possible
- The value of the shared reference type attribute
- Unable to pass parameters
Disadvantages:
function inheritObject(obj){
function F(){};
F.prototype = obj;
return new F();
}
var situation = {
companies:['bigo','yy','uc'];
area:'guangzhou';
}
var situationA = inheritObject(situation);
console.log(situationA.area) //'guangzhou'
Copy the code
9.5 Parasitic inheritance
On the basis of the original type inheritance, enhance the object, return the constructor.
Disadvantages as above
function createAnother(original){ var clone = object(original); SayHi = function(){// Make the Object alert("hi") in some way; }; return clone; } var person = {name: 'Nicholas', friends: ["Shelby","Coury","Van"] } var anotherPerson = createAnother(person)Copy the code
9.6 Extends (ES6)
Borrow ruan yifeng teacher es6 extends inheritance, eye a thousand times, rather than handwritten.Copy the code
The above can only say to deal with the interview, this is the most commonly used in our development, so must master.
Class Point {} class ColorPoint extends Point {}Copy the code
The above code defines a ColorPoint class that inherits all the properties and methods of the Point class through the extends keyword
Object.getprototypeof (ColorPoint) === Point //true; object.getProtoTypeof (ColorPoint) === PointCopy the code
Super keyword:
class A {} class B extends A { constructor() { super(); }}Copy the code
In the code above, super() in the constructor of subclass B stands for calling the constructor of the parent class. This is necessary, otherwise the JavaScript engine will report an error.
Note that super although represents the parent class constructor, but returns the instance of the subclass B, namely the inside of the super this refers to the instance of B so super () is equivalent to Amy polumbo rototype here. The constructor. Call (this).
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B
Copy the code
In the above code, new.target points to the function currently executing. As you can see, when super() executes, it points to the constructor of subclass B, not the constructor of superclass A. That is, the this inside super() refers to B.
When used as a function, super() can only be used in the constructor of a subclass, otherwise an error will be reported.
class A {} class B extends A { m() { super(); // Error}}Copy the code
In the code above, using super() in the m method of class B causes a syntax error.
In the second case, super as an object, in a normal method, points to a prototype object of the parent class; In static methods, point to the parent class.
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
}
let b = new B();
Copy the code
In the code above, super.p() in subclass B uses super as an object. In this case, super refers to a.prototype in normal methods, so super.p() equals a.prototype.p ().
It is important to note that since super refers to the parent’s prototype object, methods or properties defined on the parent instance cannot be called by super.
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
}
}
let b = new B();
b.m // undefined
Copy the code
In the code above, p is an attribute of an instance of superclass A. super.p does not refer to it.
Super can be fetched if the property is defined on a stereotype object of the parent class.
class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2
}
}
let b = new B();
Copy the code
In the code above, the attribute x is defined above a.protoType, so super.x can take its value.
ES6 states that when a method of a parent class is called through super in a subclass normal method, this inside the method refers to the current subclass instance.
class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}
let b = new B();
b.m() // 2
Copy the code
In the code above, super.print() calls a.prototype.print (), but the this inside a.prototype.print () points to an instance of subclass B, resulting in 2 instead of 1. That is, super.print.call(this) is actually executed.
Since this refers to the subclass instance, if you assign a value to a property via super, which is this, the assigned property becomes the property of the subclass instance.
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); // 3
}
}
let b = new B();
Copy the code
In the code above, assigning super.x to 3 is the same as assigning this.x to 3. When super.x is read, a.prototype. x is read, so return undefined.
If super is used as an object in a static method, then super refers to the parent class, not the parent class’s prototype object.
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
Copy the code
In the code above, super refers to the parent class in static methods and to the parent class’s prototype object in normal methods.
Also, when a method of a parent class is called through super in a static method of a subclass, the this inside the method refers to the current subclass, not the instance of the subclass.
10. Data storage and parameter transfer
let a='a'
a='b'
let b=a
Copy the code
- First create variable A, and then create string ‘a’ so variable A points to ‘a’, which holds this value
- Then create string ‘b’ and make variable a point to string ‘b’ and delete ‘a’.
- A deep copy of a(recreating ‘b’) is made so that variable B points to ‘b’, and variable A and variable B are unaffected by each other.
let obj1=new Object()
let obj2=obj1
obj1.name='node'
alert(obj2.name) //node
Copy the code
- Create an object, create a heap memory, make the variable obj1 point to the address of this object (heap memory)
- Create a variable obj2 and assign the value of obj1 to obj2, which assigns the address to obj2. In this case, obj1 and obj2 point to the same heap memory
- The two variables influence each other.
Passing parameters
Arguments to all functions are passed by value. That is, the values outside the function. Arguments copied to the inside of a function.
Function add(num){num+=10 return} var counrt=20 var result=add(counrt) alert(counrt) //20Copy the code
function setName(obj){
obj.name='node'
}
var person=new Object()
setName(person)
alert(person.name) //'node'
Copy the code
function setName(obj){
obj.name='node'
obj={name:'java'}
}
var person=new Object()
setName(person)
alert(person.name) //'node'
Copy the code
Analysis: As mentioned earlier, function arguments are passed by value. So inside the function, the local variable obj holds the address of the person object. In the first step, the name attribute at this address is ‘node’. In the second step, the variable points to a new heap address, so the external Person object is unaffected and the name attribute remains node.
11. Deep copy vs. shallow copy (write a deep copy by hand)
Because of the different data storage methods, there are shallow copies and deep copies for reference data. Shallow copy refers to copy the address, share the same heap memory, two variables affect each other, deep copy refers to, open up a memory space, store the same value. Not affected by each other.
Shallow copy:
Object.assign:, contact, extension operators, etc.
Deep copy:
1.JSON
const obj = {
arr: [1, 1],
obj: { key: 11 },
a: () => { },
date: new Date(),
reg: /reg/g,
null: null,
undefined: undefined
}
obj1 = JSON.parse(JSON.stringify(obj))
console.log(obj1)
console.log(obj1 === obj)
console.log(obj1.obj === obj.obj)
Copy the code
The output
Arr: [1, 1], obj: {key: 11}, date: '2020-04-15T07:13:36.087z ', reg: {}, null: null} false falseCopy the code
Summary: The output shows that the function and undefine are missing, and the re is an empty object.
2
function isObj (obj) { return (typeof obj === 'object' || typeof obj === 'function') && (obj ! == null) } function clone (obj) { let tempobj = Array.isArray(obj) ? [] : {} for (let key in obj) { tempobj[key] = isObj(obj[key]) ? clone(obj[key]) : obj[key] } return tempobj } let a = clone(obj) console.log(a === obj) console.log(a)Copy the code
Results:
false
{
arr: [ 1, 1 ],
obj: { key: 11 },
a: {},
date: {},
reg: {},
null: null,
undefined: undefined
Copy the code
Summary: Unable to copy functions, re, date objects.
ring
A ring is an object that refers to itself in a loop. Such as:
A = {a: 'a'} a.c = aCopy the code
Using the above two methods to copy will directly report an error. Therefore, we need to learn from the WeakMap data structure, and when copying each time, we will go to the WeakMap to check whether the object has been copied. If the object has been copied, we will remove it and return it, so we need to modify the Clone function:
function clone (obj, hash = new WeakMap()) {
if (hash.has(obj)) return hash.get(obj)
let tempobj = Array.isArray(obj) ? [] : {}
hash.set(obj, tempobj)
for (let key in obj) {
tempobj[key] = isObj(obj[key]) ? clone((obj[key]), hash) : obj[key]
}
return tempobj
}
const obj = {}
obj.obj = obj
let a = clone(obj)
console.log(a)
Copy the code
Result: The copy is successful and no error is reported.
{ obj: [Circular] }
Copy the code
Fix it, Date Reg.
function clone (obj, hash = new WeakMap()) {
let tempobj, constructor
constructor = obj.constructor
switch (constructor) {
case RegExp:
tempobj = new constructor(obj)
break;
case Date:
tempobj = new constructor(obj)
break;
default:
if (hash.has(obj)) return hash.get(obj)
tempobj = Array.isArray(obj) ? [] : {}
hash.set(obj, tempobj)
}
for (let key in obj) {
tempobj[key] = isObj(obj[key]) ? clone((obj[key]), hash) : obj[key]
}
return tempobj
}
Copy the code
Results:
{arr: [1, 1], obj: [Circular], a: [Function: a], date: 2020-04-15T08:14:03.307z, reg: /reg/g, null: null, undefined: undefined }Copy the code
The only thing left is the function.
12. Higher order functions and Currization
First, an interview question?
Const add = x => y => z=>x+y+z add(1)(2)(3) //6Copy the code
Higher-order function definition: a function that takes a function as an argument or returns a function. So the common methods are: map,filter,bind,apply and so on.
Accept arguments as functions
So let’s implement map:
[1,2,3].map((item)=>item*2) //[2,4,6].map((item)=>item*2) //[2,4,6].map((item)=>item*2) // = 0; i<this.length; I++) {arr. Push (fn (this [I], I, this)) / / call the incoming parameters} return arr} test: [1, 2, 3]. MyMap ((item) = > item * 2) / / minus [2]Copy the code
Returns the function
Currie,
Definition: The technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function) and returns a new function that takes the remaining arguments and returns the result.
Add (1)(2)(3) = 6 What if the parameters are 100? Why write it 100 times? What if the parameters are unknown, so it's not universal. For example: add (1) (2) (3) the add (1, 2, 3) (4) the add (1) (2) (3) (4) (5) the add (2, 6) (1)Copy the code
Analysis: The first thing we do is to collect all the parameters, and then carry out unified processing.
Function to the add () {/ / perform for the first time, define an Array specially used to store all the parameters of the var _args = Array. The prototype. Slice. The call (the arguments) / / in declared within a function, Var _adder = function() {_args.push(... Array.from(arguments)) return _adder }; // Use the toString implicit conversion feature, when the last execution of the implicit conversion, ToString = function () {return _args.reduce(function (a, b) {return a + b; }) } return _adder; } test: the console log (add (1) (2) (3)) / / 6 console. The log (add (1, 2, 3) (4)) / / 10. The console log (add (1) (2) (3) (4) (5)) / / 15 note: It's only when the function is evaluated that the conversion is done, that toString is called to return the value that was added otherwise it's just called to return the function instead of the added valueCopy the code
13.ajax
Ajax is a collection of techniques for sending and receiving data to the server without refreshing the page.
const xhr = new XMLHttpRequest()
Copy the code
XMLHttpRequest is an API provided by the browser and, in JS, a constructor.
Simply complete an Ajax request: const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { if (xhr.readystate == 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { alert(xhr.responseText) } else { alert(xhr.status) } } } xhr.open("get", "user", true) xhr.send(null)Copy the code
Readystate is an instance property:
- 0: uninitialized — the.open() method has not been called
- 1: start — the.open() method has been called, but the.send() method has not;
- 2: send — the.send() method has been called, but no response has been received;
- 3: Receive: some response data has been received.
- 4: Completed — all response data has been received and is ready for use on the client.
Status is the response status code (HTTP status), different from readyState.
Cancel the asynchronous
Ajax can also disable event listening, change asynchrony to synchronization, and call abort()
The progress schedule:
- Loadstart: Fired when the first byte of response data is received
- Progress: Continuous firing during the receipt of a response
- Error: Triggered when an error occurs in the request.
- Load: triggered when the complete response data is received;
- Oadend: triggered after the communication completes or after the error, abort, or load event is triggered
14.DOM
Add, delete, change and check DOM elements
Add: Adds a DOM element
- AppendChild: Adds a new child node to the end of the child node list of the current node
- InsertBefore (newchild, refchild): where newchiild indicates that a new node is inserted, refchild indicates that a newchild node is inserted before this node, and the newchild node is returned:
Document. Body. InsertAdjacentHTML (' beforeend ', '< b > hello < / a >')Copy the code
This method allows you to insert any valid HTML string into a DOM element at four positions specified by the first argument to the method:
- ‘beforeBEGIN ‘: Precedes the element
- ‘AfterBEGIN ‘: Inside the element, before the first existing child element
- ‘beforeend’: Inside the element, after the last existing child element
- ‘afterend’: after the element
<! -- beforebegin --> <div> <! -- afterbegin --> <span></span> <! -- beforeend --> </div> <! -- afterend --Copy the code
Deleting dom elements
Method 1: const target = document. QuerySelector (' target ') target. ParentNode. RemoveChild (target) method 2: const target = document.querySelector('#target') target.remove()Copy the code
Move the dom:
<h1>frist</h1>
<p>1</p>
<h2>two</h2>
Copy the code
Using the previous insertAdjacentHTML approach:
const h1 = document.querySelector('h1')
const h2 = document.querySelector('h2')
h1.insertAdjacentElement('afterend', h2)
Copy the code
Results:
<h1>frist</h1>
<h2>two</h2>
<p>1</p>
Copy the code
Replacing dom elements
parentNode.replaceChild(newNode, oldNode)
oldElement.replaceWith(newElement)
Copy the code
Dom detection:
- Matches: Checks whether an element matches a certain selector
- Contains: Detects whether an element contains another element
Dom Observer: MutationObserver
When dealing with user interaction, there are often many changes to the DOM elements of the current page, and some scenarios require developers to listen for these changes and perform actions when triggered. MutationObserver is a browser-provided interface designed to listen for DOM changes. It is powerful enough to observe almost all changes to an element, including text changes, addition and removal of child nodes, and changes to any element attributes. As always, if you want to construct any object, new its constructor:
const observer = new MutationObserver(callback)
Copy the code
The copy code passes into the constructor a callback function that is executed when the DOM element being listened for changes, taking MutationRecords, the list of all the changes, and the Observer itself. Where each entry of MutationRecords is a change record, it is a common object containing the following common properties:
- Type: Change type, Attributes/characterData/childList
- Target: the DOM element that was changed
- AddedNodes: Adds NodeList consisting of child elements
- RemovedNodes: NodeList with removed child elements
- AttributeName: The name of the attribute whose value changed, or null if not
- PreviousSibling: The sibling node before the child element to be added or removed
- NextSibling: The sibling node after the child element that is added or removed
Based on the current information, we can write a callback function:
const callback = (mutationRecords, observer) => { mutationRecords.forEach({ type, target, attributeName, oldValue, addedNodes, removedNodes, } => { switch(type) { case 'attributes': console.log(`attribute ${attributeName} changed`) console.log(`previous value: ${oldValue}`) console.log(`current value: ${target.getAttribite(attributeName)}`) break case 'childList': console.log('child nodes changed') console.log('added: ${addedNodes}') console.log('removed: ${removedNodes}') break // ... }})}Copy the code
At this point, we have a DOM observer, and a fully available DOM callback, except for one DOM element that needs to be observed:
const target = document.querySelector('#target')
observer.observe(target, {
attributes: true,
attributeFilter: ['class'],
attributesOldValue: true,
childList: true,
})
Copy the code
In the above code, we observe the DOM element id target (the first parameter is the object to observe) by calling the observe object’s observe method. For the second element, we pass in a configuration object: Enable observation of attributes/Only observation of class attributes/passing old values of attributes when attributes change/Enable observation of lists of child elements. The configuration object supports the following fields:
- Attributes: Boolean, whether to listen for changes to element attributes
- AttributeFilter: String[], an array of specific attribute names to listen on
- AttributeOldValue: Boolean, whether the last value of the listening element’s attribute is logged and passed when the attribute changes
- CharacterData: Boolean, whether to listen for changes in characterData contained by nodes in the target element or child element tree
- CharacterDataOldValue: Boolean, whether to record and pass the previous value of character data when it changes
- ChildList: Boolean, whether to listen to the target element to add or remove child elements
- Subtree: Boolean, whether to extend the monitoring scope to all elements of the entire subtree under the target element
When the change of the target element is no longer monitored, the Observer’s Disconnect method can be called. If necessary, the Observer’s takeRecords method can be first called to remove all pending notifications from the Observer’s notification queue. And returns them to an array of MutationRecord objects:
const mutationRecords = observer.takeRecords()
callback(mutationRecords)
observer.disconnect()
Copy the code
15.BOM
BOM is the browser object model, which will be reviewed one by one.
Window
All JavaScript global objects, functions, and variables automatically become members of the Window object.
Global variables are properties of the window object.
Global functions are methods of the window object.
Even the DOCUMENT of the HTML DOM is an attribute of the window object:
- Window.innerheight – The internal height of the browser window (including the scroll bar)
- Window.innerwidth – the innerWidth of the browser window (including the scroll bar)
- Window.open () – Opens a new window
- Window.close () – Closes the current window
- Window.moveto () – Moves the current window
- Window.resizeto () – Resizes the current window
Global variables cannot be deleted by the DELETE operator; Variables defined on the window property can be deleted by delete
var num=123;
window.str="string";
delete num;
delete str;
console.log(num); //123
console.log(str); //str is not defined
Copy the code
Accessing undeclared variables throws an error, but by querying the Window object, you know if a variable that might not be declared exists.
var newValue=oldValue; OldValue is not defined var newValue=window.oldValue; Console. log(newValue); // undefinedCopy the code
screen
- Screen. availWidth – The available screen width
- Screen. availHeight – Available screen height
location
The window.location object is used to get the address (URL) of the current page and redirect the browser to the new page.
- Location. href returns the URL of the current page
- Location. hostname Returns the domain name of the Web host
- Location. pathName Returns the path and filename of the current page
- Location. port Returns the port of the Web host (80 or 443)
- Location. protocol Returns the Web protocol used (HTTP: or HTTPS:)
Window.location. assign(url) : loads a new HTML document specified by the URL. It is equivalent to a link, jump to the specified URL, the current page will be converted to the new page content, you can click back to return to the previous page.
Window.location. replace(URL) : Replaces the current document by loading the document specified by the URL. This method replaces the current window page
history
The window.history object contains the history of the browser
- History.back () – same as clicking the back button in your browser
- History.forward () – same as clicking the forward button in your browser
- History. go(index):index indicates the number of steps forward or backward, and 0 indicates the page refresh
navigator
The window.navigator object contains information about the visitor’s browser
Wrap objects
Packaging object:
In fact, it is an object. When operating on basic type data, a corresponding object will be created first, and then deleted after the operation.
The difference between:
The difference between a reference type and a primitive wrapper object is that the lifetime, the object created by a reference type, remains in memory for the duration of execution, whereas a primitive wrapper object only exists for a fraction of a second (that is, the variable becomes null after execution).
var a='aa'
typeof a // 'string'
a.slice(1) //'a'
Copy the code
A is a primitive type of data that does not have any methods, but we can call the slice method to wrap a layer of objects. If it’s an object, we can add attributes
a.name='aaa'
console.log(a.name) //undefined
Copy the code
But the access is not accessible. As mentioned earlier, the wrapper object is deleted after the operation, that is, the A.name only exists for a moment.
17. Encapsulation, polymorphism
Polymorphism:
Polymorphism is a kind of polymorphism processing mechanism that can be realized by executing logic by judging the parameters passed.
function args(... Args){if(array.from (args).length==1){console.log(' one parameter ')} if(array.from (args).length==2){console.log(' two parameters ')}}Copy the code
encapsulation
Encapsulation is to encapsulate objective things into abstract classes, hide the implementation details of attributes and methods, and only expose interfaces. In other words, encapsulation is the process of putting attributes and methods together into a class called encapsulation.
Var a={name:'nihao', do:function(){}}Copy the code
- Advantages: The code is simple and easy to understand
- Disadvantages: Creating multiple objects is a lot of code, cumbersome to write, and there is no concept of instances and prototypes
Function createPerson(name, age) {var person = new Object(); person.name = name; person.age = age; person.do= function() { alert('hello word! '); }; return person; } const person1=createPerson('curry',31)Copy the code
- Advantages: Avoid code bloat when creating a large number of objects
- Disadvantages: There is no internal connection between P1 and P2
Constructor: function Person(name, This.name = name this.age = age this.action = function () {alert('hello word')} P1 = new Person(' y ', 20) var p2 = new Person(' y ', 20)Copy the code
- Advantages: There is an association between the instantiated object and the constructor
- Disadvantages: Waste of memory, the constructor defines the same method name action, but the instantiated object name is not the same, resulting in a waste of memory
Prototype mode: function Person(name, This.name = name this.age = age} person.prototype. action = function () {this.name = name this.age = age} Alert ('hello wodr')} var p1 = new Person(' hello wodr', 18) var p2 = new Person(' hello wodr', 20) p1.action() p2.action()Copy the code
18. Catch a try catch
Can a JS exception be caught by a try catch?Copy the code
Correct answer: Only exceptions that are thrown when a thread has entered a try catch can be caught. That is, only errors that sync JS code can be caught.
Example 1: Try {c.}catch(e){console.log("error",e); } // output Uncaught SyntaxError: Unexpected token '}'Copy the code
When code fails, thread execution does not enter a try catch, so no exception can be caught.
Syntaxerrors, for example, are reported during the syntax check phase and cannot be caught before the thread has entered the try catch block.
Example 2: Try {setTimeout(a,100)}catch(e){console.log("error",e); } Uncaught ReferenceError: a is not definedCopy the code
SetTimeout error, in fact, the code executed after 100ms error, at this time the code block try catch has been completed, 111 has been executed, so the exception cannot be caught.
Try {function d(){a.b; } d(); }catch(e){ console.log("error",e); } // error ReferenceError: a is not definedCopy the code
A promise exception can be caught by a catch instead of wrapped in a try catch.
19. Single threads and event loops
Single thread
Js runs in a browser, which is multi-process and multi-threaded. But assigned to Js, there is only one thread. Because Js can manipulate dom, Js and DOM rendering must be mutually exclusive. Otherwise, it’s dom rendering and JS manipulating the DOM, so who does the browser listen to? Multithreading brings its own level of complexity.
Single-threaded tasks are executed in sequence, and the next task can be executed only after the previous task is completed. If one task takes so much time that subsequent tasks have to wait, then the language is too bad. So there are asynchronous tasks and callback functions. This means that the time-consuming task is handed over to another thread to execute, and when the task is finished, the callback function is triggered. So it does not obstruct the execution of JS synchronization tasks. Now the question is, how are these callback functions executed, and in what order?
Event loop
The browser maintains an event queue that checks for any tasks that need to be executed at appropriate intervals after the main thread task has completed. Task is divided into macro task and micro task, macro task is faster than micro task.
- Common macro tasks: Script (overall code), setTimeout, setInterval, I/O, setImmedidate, Ajax
- Common microtasks: Process. nextTick, MutationObserver, Promise.then catch finally
The overall execution sequence is shown in the figure above:
- Start with a macro task
- Check for microtasks and execute them all. (All microtasks generated by microtasks are also executed), and then the microtask queue is emptied
- Apply colours to a drawing
– Start the next macro task more said than done:
Example 1: // Resolve (). Then (function() {console.log('promise1')})}, Resolve ().then(function() {console.log('promise2')}) // Set3 setTimeout(() => {console.log('timer3')}, 0)}, 0) Promise.resolve().then(function() { console.log('promise3') }) console.log('start')Copy the code
Running process
Loop a
- 1. Put the script task into the Task queue.
- 2, Select a task from the task, run the result set1 and set2 into the task, put promise. Then into the microtask, output start.
- 3. Check the Microtask checkpoint to check whether there are tasks in the Microtask queue.
- 4. Run all microTask tasks and output promise3.
- 5. After clearing the MicroTask queue, proceed to the next loop.
Loop 2
- 1. Retrieve a set1 task from task, which outputs timer1 and places promise.then on the MicroTask queue.
- 2. Check the Microtask checkpoint to check whether there are tasks in the Microtask queue.
- 3. Run all microTask tasks and output promise1.
- 4. After clearing the MicroTask queue, proceed to the next loop.
Cycle three
- 1, Retrieve a set2 task from the task, output timer2, place promise. Then into the microtask queue, and place SET3 into the task queue.
- 2. Check the Microtask checkpoint to check whether there are tasks in the Microtask queue.
- 3. Run all microTask tasks and export promise2.
- 4. After clearing the MicroTask queue, proceed to the next loop.
Loop four
- Timer3 = timer3; timer3 = timer3; timer3 = timer3
- 2. Check the microtask checkpoint to check whether there are no tasks in the microtask queue and proceed to the next loop.
Loop five
- Check that both the Task and MicroTask queues are empty, the Closing flag bit in the WorkerGlobalScope object is true, and the Event Loop is destroyed.
Output result
start
promise3
timer1
promise1
timer2
promise2
timer3
Copy the code
20.promise
Ruan Yifeng teacher elaborate promise
21. The es6 modular
Ruan Yifeng lectured es6 modularity
Conclusion:
I hope my article is helpful to you. The remaining two articles will be released within a week, and they are almost finished. I hope you can give me a lot of support.