JS article
Js data type
1. Js has several data types, which are the basic data types
Seven data typesCopy the code
Boolean
Null
Undefined
Number
String
Symbol
(New ECMAScript 6 definition)Object
(ES6) before the five basic types: string, number, Boolean, null, and undefined
ES6 Symbol is also a primitive data type, representing unique values
Object is a reference type (a large range), which also includes arrays and functions
2, null and undefined
In general, if you want to know why, search the engine
Similarities:
- In the if statement, the value defaults to false
- In general, both represent nothing, depending on the specific differences
Differences:
null
Converted to a numeric type the value is 0 and undefined is converted to a numeric typeNaN(Not a Number)
undefined
Is for calling a value without assigning a value, in which case the default isundefined
null
Is a very special object, and one of the most common uses is to pass it as a parameter.- Set to
null
Is collected by the memory collector
3. What is the difference between == and ===
JS object
1. Native objects and methods
1.1. The method of changing the original array
- Methods to change the original array:
Pop, push, reverse,shift, sort, splice, unshift, and two new ES6 methods copyWithin and Fill;Copy the code
- Do not change the original array (copy) :
Concat, Join, slice, toString, toLocaleString, indexOf, lastIndexOf, non-standard toSource, and new ES7 methods includes;Copy the code
- Loop through:
forEach, every, some, filter, map, reduce, reduceRight and ES6 new methods Entries, find, findIndex, keys and values.Copy the code
1.2. Differences between Splice and slice, map and forEach, filter() and reduce()
- 1.
slice(start,end)
The: method returns the selected element from an existing array, returning a new array containing the elements fromstart
toend
Note: This method does not update the original array, but returns a subarray- 2.
splice()
This method adds or removes items from an array and returns the deleted items. (This method changes the array)splice(index, howmany,item1,... itemx)
The index,
Arguments: Mandatory, integers specify where to add or remove, and negative numbers specify where to add or remove from the end of the arrayHowmany,
Parameters: must, number to delete,Item1,.. itemx:
Optionally, add a new item to the array- 3.
map()
: returns a brand new array. Used when changing data values. Allocates an array of memory storage space and returns,The forEach ()
Does not return data- 4.
forEach()
: does not return anything of value and does not intend to change the data, but simply wants to do something with it, he allowscallback
Changes the elements of the original array- 5.
reduce()
The: method takes a function as an accumulator, starting with each value in the array (left to right), and eventually computes a value without changing the value of the original array- 6.
filter()
The: method creates a new array by checking all eligible elements in the specified array. It goes throughfunction
To do the processing
- String
methods | describe |
---|---|
charAt() | Returns the character at the specified position. |
charCodeAt() | Returns the Unicode encoding of the character at the specified position. |
concat() | Connection string. |
indexOf() | Retrieves the string. |
match() | Finds a match for one or more regular expressions. |
replace() | Replaces the substring that matches the regular expression. |
search() | Retrieves the value that matches the regular expression. |
slice() | Extracts a fragment of a string and returns the extracted portion in a new string. |
split() | Splits a string into an array of strings. |
toLocaleLowerCase() | Converts a string to lowercase. |
toLocaleUpperCase() | Converts the string to uppercase. |
toLowerCase() | Converts a string to lowercase. |
toUpperCase() | Converts the string to uppercase. |
substr() | Extracts a specified number of characters from the initial index number in the string. |
substring() | Extracts the character between two specified index numbers in a string. |
-** Array**
methods | describe |
---|---|
slice[start,end) | Returns a new array of items from the specified start index to the end index (without affecting the original array) |
: | . 1 parameter: n. That is, all from n to the end |
: | . 2 parameters: [start,end] |
Splice () : | . Delete: 2 parameters, starting position, number of items to delete |
: | .Insert: 3 arguments, start position, number of items to delete, inserted items |
: | . Replace: Any argument, start position, number of items to delete, insert any number of items |
pop() | Removes the last element of the array, reducing the length of the array, and returns the deleted value. (no arguments) |
push() | Load the argument to the end of the array, returning the length of the new array. (Parameter no limit) |
shift() | Deletes the first element of the array, the array length is reduced by 1, and returns the deleted value. (no arguments) |
unshift() | Adds one or more elements to the beginning of the array and returns the new length. (Parameter no limit) |
sort() | Sorts an array by the specified argument. Returns the sorted array (no arguments/functions). |
Concat (3, 4) | Concatenate the two arrays. The value returned is a copy (parameters are unlimited) |
join() | Group the elements of the array into a string using separator as a separator and, if omitted, comma as the default separator |
indexOf() | Looking backwards from the beginning of the array takes two arguments, the item to look for (optional) and the index of the starting position to look for |
lastIndexOf() | Looking forward from the end of the array takes two parameters, the item to look for (optional) and the index at which the search started |
every() | Run the given function on each item in the array, returning true if the function returns true for each item. |
filter() | Run the given function on each item in the array and return the items that return true to form the array. |
forEach() | Run the given function on each item of the array. This method returns no value. |
map() | Run the given function on each item of the array, returning the array as a result of each function call. |
some() | Runs the given argument on each item in the array, and returns true if the function returns true for any item. None of the above methods modify the values contained in the array. |
Reduce () and reduceRight () | Methods that shrink an array. Both of these methods iterate over all the items in the array and then build a value that is eventually returned. |
- regular
methods | describe |
---|---|
compile | Compile regular expressions. |
exec | Retrieves the value specified in the string. Returns the value found and determines its position. |
test | Retrieves the value specified in the string. Returns true or false. |
search | Retrieves the value that matches the regular expression. |
match | Finds a match for one or more regular expressions. |
replace | Replaces the substring that matches the regular expression. |
split | Splits a string into an array of strings. |
Recommendation: Knowing these 20 regular expressions will save you 1,000 lines of code
Interview with some JavaScript algorithms
2. Several methods of creating objects and their advantages and disadvantages
Prototype/constructor/instance
-
Prototype: A simple object used to implement object property inheritance. Can be simply understood as the father of the object. In Firefox and Chrome, each JavaScript object contains a __proto__ (nonstandard) attribute pointing to its parent (the object’s prototype), accessible from obj.__proto__.
-
Constructor: a function that creates an object using new.
-
Instance: Objects created through constructors and new are instances. Instances point to prototypes via __proto__ and to constructors via constructor.
2.1. Factory Mode
The factory pattern is a well-known design pattern in software engineering that abstracts the process of creating concrete objects
function createPerson(name, age, job) {
let o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function () {
console.log(this.name);
}
return o;
}
let person1 = createPerson("Nicholas", 29, "Software Engineer");
let person2 = createPerson("Greg", 27, "Doctor");
Copy the code
The factory pattern solves the problem of creating multiple similar objects, but it does not solve the problem of object recognition (how to know the type of an object)
2.2. Constructor pattern
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() { console.log(this.name); }}let person1 = createPerson("Nicholas", 29, "Software Engineer");
let person2 = createPerson("Greg", 27, "Doctor");
Copy the code
The main problem with using constructors is that each method is recreated on each instance (person1.sayname! == person2.sayName)
2.3. Prototype mode
Each function we create has a Prototype property, which is a pointer to an object whose purpose is to contain properties and methods that can be shared by all instances of a particular type
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
Copy the code
All attributes in the stereotype are shared by the instance, and attributes of reference types are problematic
function Person(){} Person. Prototype = {constructor: Person, // Const constructor = {constructor: Person, // const constructor: Person;"Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby"."Court"],
sayName : function() { alert(this.name); }}; var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van");
console.log(person1.friends); //"Shelby,Court,Van"
console.log(person2.friends); //"Shelby,Court,Van"
console.log(person1.friends === person2.friends); //true
Copy the code
2.4. Use a combination of constructor and stereotype patterns
The most common way to create custom types is to combine the constructor pattern with the stereotype pattern. The constructor pattern is used to define instance properties, while the stereotype pattern is used to define method and shared properties. As a result, each instance has its own copy of instance properties, but also shares references to methods, maximizing memory savings.
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby"."Court"];
}
Person.prototype = {
constructor : Person,
sayName : function(){
console.log(this.name);
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
console.log(person1.friends); //"Shelby,Count,Van"
console.log(person2.friends); //"Shelby,Count"
console.log(person1.friends === person2.friends); //false
console.log(person1.sayName === person2.sayName); //true
Copy the code
In this case, the instance properties are defined in the constructor, while the constructor property and method sayName(), shared by all instances, are defined in the stereotype. Changing person1.friends (adding a new string to it) does not affect person2.friends because they reference different arrays. This constructor/prototype hybrid pattern is currently the most widely used and recognized method of creating custom types in ECMAScript. This is the default mode for defining reference types, so to speak.
2.5. Dynamic prototyping
All information is encapsulated in the constructor, and by initializing the stereotype in the constructor (only when necessary), you retain the advantage of using both the constructor and the stereotype. In other words, you can determine whether a stereotype needs to be initialized by checking whether a method that should exist is valid.
functionPerson(name, age, job){// attribute this.name = name; this.age = age; this.job = job;if(typeof this.sayName ! ="function"){
console.log(1);
Person.prototype.sayName = function(){
console.log(this.name);
};
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer"); //1
var person2 = new Person("Greg", 27, "Doctor");
person1.sayName();
person2.sayName();
Copy the code
Here the sayName() method is only added to the stereotype if it does not exist. This code is executed only when the constructor is first called. Since then, the prototype has been initialized and no further changes are required. Keep in mind, however, that any changes made to the prototype here are immediately reflected in all instances. So this approach is really perfect where if statements can check for any property or method that should exist after initialization — you don’t have to check for every property and every method with a bunch of if statements; Just check one of them. For objects created in this pattern, you can also use the instanceof operator to determine its type.
2.6. Parasitic constructor patterns
The basic idea is to create a function that simply encapsulates the code that created the object and then returns the newly created object. On the surface, however, this function looks like a typical constructor
function Person(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
};
return o;
}
var p1 = new Person("Nicholas", 29, "Software Engineer");
p1.sayName(); //"Nicholas"
Copy the code
The Person function creates a new object, initializes it with the appropriate properties and methods, and then returns it. This pattern is exactly the same as the factory pattern, except that we use the new operator and call the wrapper function we use a constructor, which by default returns a new object instance without a value. By adding a return statement to the end of the constructor, you can override the value returned when the constructor is called.
This pattern can be used in special cases to create constructors for objects. Suppose we want to create a special array with extra methods. Because you cannot modify the Array constructor directly, you can use this pattern.
function SpecialArrayVar values = new Array(); // Add values values.push.apply(values, arguments); // Add method values.topipedString =function() {return this.join("|"); }; // Return an arrayreturn values;
}
var colors = new SpecialArray("red"."blue"."green");
alert(colors.toPipedString()); //"red|blue|green"
Copy the code
There are a few things to note about the parasitic constructor pattern: First, there is no relationship between the object returned and the constructor or the stereotype properties of the constructor; That is, the object returned by the constructor is no different from the object created outside the constructor. For this reason, you cannot rely on the Instanceof operator to determine the object type. Because of the above, we recommend against using this pattern when other patterns are available
2.7. Secure constructor pattern
A secure object is an object that has no public attributes and whose methods do not reference this. Secure objects are best used in secure environments where the use of this and new is prohibited, or to prevent data from being altered by other applications. The secure constructor follows a similar pattern to the parasitic constructor, but with two differences: the newly created object instance method does not reference this; The second is to call the constructor without using the new operator. For the sake of a safe constructor, you can rewrite the previous Person constructor as follows.
functionPerson(name, age, job){// Create the Object to return var o = new Object(); // Private variables and functions can be defined here // add methodfunction(){ alert(name); }; // Return the objectreturn o;
}
Copy the code
Note that in objects created in this pattern, there is no way to access the value of name other than using the sayName() method. You can use the prudent Person constructor as follows.
var person = Person("Nicholas", 29, "Software Engineer");
person.sayName(); //"Nicholas"
Copy the code
Thus, the person variable holds a secure object, and there is no other way to access its data members than by calling the sayName() method. Even if other code adds methods or data members to the object, there is no other way to access the raw data passed into the constructor. This security provided by the secure constructor pattern makes it ideal for use in certain secure execution environments.
3. This object and its pointer
Change the pointer to this inside a function.
-
The first argument to apply and call is the same as the object to be changed. The second argument, apply, is an array, and call is arg1,arg2… In this form.
-
Changing the this scope by bind returns a new function that will not be executed immediately.
Implement the call method manually:
Function.prototype.myCall = function(context = window, ... rest) { context.fn = this; // This refers to the myCallfunction
letresult = context.fn(... rest); // Add this to delete context.fn;return result;
};
Copy the code
Implement the Apply method manually:
Function.prototype.myCall = function(context = window, params = []) { context.fn = this; // This refers to the myCallfunction
let result
if(params.length) { result = context.fn(... params) }else{result = context.fn()} // Add this to delete context.fn;return result;
};
Copy the code
Manually implement the bind method:
Function.prototype.myBind = function(oThis, ... rest) {let _this = this;
let F = function() {} // According tobindSpecifies if the new operator is used to constructbindThe first argument bound to this is invalidatedlet resFn = function(... parmas) {return_this.apply(this instanceof resFn ? this : oThis, [...rest,...parmas]); }; // Inherit the prototypeif (this.prototype) {
F.prototype = this.prototype;
resFn.prototype = new F;
}
return resFn;
};
Copy the code
Hi, do you really understand this?
Shallow copy and deep copy
Shallow copy is to copy all the values belonging to the source object to the new object without creating a separate memory area for the two objects.
Deep copy is completely two separate areas of memory that do not interfere with each other
- Shallow copy
// This is ES5function shallowClone(sourceObj) {// Check whether the type passed in is an object typeif (!sourceObj || typeof sourceObj ! = ='object') {
console.log('You passed in an object!! 'Var targetObj = var targetObj = var targetObj =sourceObj.constructor === Array ? [] : {}; // iterate over all keysfor (var keys in sourceObj) {// Determine all keys that belong to its own prototype chain, not those that inherit (upstream)if (sourceObj. HasOwnProperty (keys)) {// copy targetObj[keys] =sourceObj[keys]; }}returntargetObj; } // ES6 can use object. assign(targeObj,source1,source2,source3) to implement a shallow copy of the objectCopy the code
- Deep copy
// Stringify can serialize a JS object into a JSON string, Parse can deserialize JSON strings into a JS object var deepClone =function(sourceObj) {
if (!sourceObj || typeof sourceObj ! = ='object') {
console.log('You passed in an object!! ');
return; } // Go -> parse -> Return in one stepreturn window.JSON
? JSON.parse(JSON.stringify(sourceObj))
: console.log('Your browser does not support the JSON API');
};
Copy the code
- Deep copy considerations are actually more complex
Prototype chains and inheritance
Js Everything is an object, with
var a={}
orvar a = new Object()
Or use the constructor form:var a = new A()
When an object is created, the object not only has access to its own properties, but also has access to properties based on__proto__
Property finds the property on its prototype chain until it findsObject
The abovenull
Every Function has a prototype attribute, except function.prototype.bind (), which points to the prototype.
Each object has a __proto__ attribute that points to the prototype of the constructor that created the object. [[prototype]] is an internal attribute that we can’t access, so use _proto_.
Objects can find properties that are not part of the object by __proto__, which links objects together to form a prototype chain.
- Prototype chain inheritance:
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'
; Multiple inheritance cannot be implemented- Constructor inheritance: Use the parent class’s constructor to enhance a subclass instance.
function Cat(name){Animal.call(this); this.name = name || 'Tom'; }
Cannot inherit properties and methods from the parent stereotype chaininstallof
To test
- Instance inheritance: Adds new features to the parent class instance as a return for the subclass instance
- Copy inheritance: copying attributes and methods from a parent element
- Combinatorial inheritance: a combination of constructive inheritance and archetypal inheritance
- Parasitic combinative inheritance: By parasitic, add a ·Super· function (no instance or method) to the constructor inheritance to make it point to the parent’s constructor chain and cut off the instance properties of the parent class, so that when the constructor of the parent class is called twice, the method/properties of the parent class are not initialized twice
1. Prototype chain inheritance
- Features: Based on the prototype chain, it is both an instance of a parent class and an instance of a subclass
- Disadvantages: Cannot implement multiple inheritance
// Define an animal classfunctionAnimal (name) {/ / attribute this. Name = name | |'Animal'; // Instance method this.sleep =function(){
console.log(this.name + 'Sleeping! '); } // Animal.prototype.eat =function(food) {
console.log(this.name + 'Eating:'+ food); }; -- Prototype chain inheritancefunction Cat(){ }
Cat.prototype = new Animal();
Cat.prototype.name = 'cat'; //  Test Code var cat = new Cat(); console.log(cat.name);Copy the code
2. Structural inheritance
Using the constructor of the parent class to enhance the instance of the child class is equivalent to copying the instance properties of the parent class to the child class (without using the stereotype).
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
// Test Code
var cat = new Cat();
console.log(cat.name);
Copy the code
- Features: Can achieve multiple inheritance
- Disadvantages: Can only inherit the attributes and methods of the parent instance, not the attributes and methods of the prototype.
3. Combinatorial inheritance
It is equivalent to the combination of structure inheritance and prototype chain inheritance. By calling the superclass constructor, the attributes of the parent class are inherited and the advantages of passing arguments are retained. Then, functions can be reused by using the instance of the parent class as the prototype of the subclass
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);
Copy the code
- Features: You can inherit instance properties/methods as well as stereotype properties/methods
- Disadvantages: Called the superclass constructor twice, generating two instances
4. Parasitic combination inheritance
In a parasitic manner, instance attributes of the parent class are cut off so that two instance methods/attributes are not initialized when a construct of the parent class is called twice
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){// create a class with no instance methodsfunction() {}; Super.prototype = Animal.prototype; Cat.prototype = new Super(); }) (); // Test Code var cat = new Cat(); console.log(cat.name);Copy the code
See Lewis’ article on JS prototype chains and Inheritance for more details
Function scope
1. What is the scope of JS? What’s so special about it?
The concept of scope for a variable is the scope within which a variable can be used
JS first has the outermost scope: it is called the global scope
JS can also create a separate scope from functions, where functions can be nested, so scopes can also be nested
2. Scope chain
The scope chain is composed of the current scope and a series of parent scopes. The head of the scope is always the current scope and the tail is always the global scope. Scope chains guarantee ordered access by the current context to variables to which it is entitled.
Scoped chain meaning: Find variables (determine where the variable came from and whether the variable is accessible)
In short, scope chains can be summed up in the following sentence: (or: Determine which scope a variable comes from)
View the current scope and determine the result if the current scope declares the variable
Find the parent scope of the current scope, that is, the parent function of the current function, to see if there are declarations in the parent function
Then look for the parent function’s parent function, up to the global scope
If not in the global scope, we consider the variable undeclared (XXX is not defined)
This article is recommended to go as far as possible into JS series – scope chain
Function declarations VS function expressions
Function declarations and function expressions are judged by whether the declaration of a function begins with the function keyword. Declarations that start with the keyword function are function declarations, and the rest are all function expressions.
// Function declarationfunction foo() {} // Function expression var foo =function() {}; (function() {
})();
Copy the code
Named functions VS anonymous functions
- Named function A function that has a name
function foo() {
}
var foo = function bar() {}setTimeout( function foo() {}) +function foo() {
}();
Copy the code
Note: Function declarations must be named functions.
- Anonymous function A function without a name
var foo = function() {}setTimeout( function foo() {
} )
-function foo() {
}();
Copy the code
- Execute functions now (IIFE)
vara=2;
(function foo() { var a=3; console.log( a ); / / 3}) (); console.log( a ); / / 2Copy the code
- Another way of expressing it
(function() {
}())
Copy the code
5, closures
5.1, definitions,
Closures result when a function can remember and access its lexical scope, even if the function is executed outside the current lexical scope. ---- Javascript You Didn't Know, Volume 1Copy the code
A closure is a function that can access and manipulate variables inside other functions. Or a function defined inside a function. Because JavaScript doesn’t have dynamic scope, and closures are static scoped by nature (static scoping rules look for a variable declaration depending on the static relationship between blocks in the source program), functions access the scope we defined, the lexical scope. That’s why closures are implemented.
The common closure form is that function A covers function B, and then function A returns function B, so that function B can still access function A’s scope when executing outside of function A. The real power of closures comes from the fact that function B executes somewhere other than function A.
function fn1() {
var name = 'iceman';
function fn2() {
console.log(name);
}
return fn2;
}
var fn3 = fn1();
fn3();
Copy the code
This shows the closure clearly:
-
The lexical scope of fn2 accesses the scope of Fn1
-
Return fn2 as a value
-
After fn1 is executed, a reference to fn2 is assigned to fn3
-
Execute fn3 and output the variable name
We know by reference that fn3 is the fn2 function itself. Executing fn3 normally outputs name, which means that fn2 can remember and access the lexical scope in which it is located, and that the fn2 function is still running outside the current lexical scope.
Normally, when the fn1 function completes, its scope is destroyed and the garbage collector frees that memory. Closures magically keep fn1’s scope alive, and FN2 still holds a reference to that scope, which is the closure.
Conclusion: Closures give a function limited access to a defined lexical scope when it is called outside of its lexical scope.Copy the code
5.2. Conditions for closure formation
- Nested function
- An inner function refers to a local variable of an outer function
5.3. Closure features
Every function is a closure, and every function is inherently capable of remembering the scope in which it was defined. Move a function out of its defined scope and run it. This function is surprisingly capable of remembering the scope at which it was defined. No matter where the function goes, the scope of the definition goes there. Let’s use two examples to illustrate this problem:
Var inner;function outer(){
var a=250;
inner=function(){ alert(a); }} outer();}} outer(); var a=300; inner(); // When a function executes, it looks for variables in the closure, regardless of the current scope.Copy the code
/ / sample 2function outer(x){
function inner(y){
console.log(x+y);
}
returninner; } var inn=outer(3); // After passing the number 3 to outer, x in inner remembers inn(5); // When inner passes 5, only y is assigned, so 8 pops upCopy the code
5.4. Closure memory leaks
Stack memory provides an execution environment, i.e. scope, including global scope and private scope. When do they free memory?
- Global scope —- The global scope is destroyed only when the page is closed
- The private scope —- is generated only by function execution
Normally, the execution of a function creates a new private scope, and when the execution of the code in the private scope is complete, the current scope is actively released and destroyed. However, when a function execution returns a value that refers to a datatype and is received by something else outside of the function, the private scope generally formed in this case is not destroyed.
Such as the following situation:
function fn(){
var num=100;
return function(){ } } var f=fn(); // The private scope created by the fn execution cannot be destroyedCopy the code
The private scope inside the fn function will always be occupied. There is a memory leak.
A memory leak is any object that persists after you no longer own or need it. Closures should not be abused because they can leak memory and affect web page performance. Immediately after the closure is used, the resource is freed and the reference variable is pointed to NULL.
Let’s look at a classic interview question about memory leaks:
function outer(){ var num=0; // Internal variablesreturn function add() {/ / passreturnReturn add to access num++ outside outer; // Internal functions are referenced as part of the add function console.log(num); }; } var func1=outer(); func1(); // Actually call the add function, printing 1 func1(); Var func2=outer(); var func2=outer(); func2(); // Output 1 The closure is brand new each time the function is rereferenced. func2(); 2 / / outputCopy the code
5.5. The role of closures
- You can read variables inside a function.
- The value of a variable can be kept in memory for a long time with a long life cycle. Therefore, you should not abuse closures, which can cause performance problems for your web pages
- Can be used to implement JS modules.
JS module: with a specific function of the JS file, all the data and functions are encapsulated in a function inside (private), only to expose a package n method object or function, the user of the module, only through the object exposed by the module to call the method to achieve the corresponding function.
5.6. Use of closures
The main application of closures is to design private methods and variables.
Recommended articles:
JavaScript closures
Efficient use of JavaScript closures
6. The new operator
Talk about the new operator
7. Execution Context (EC)
An execution context can be understood simply as an object:
-
It consists of three parts:
- Variable Object (VO)
- Scope chain (lexical scope)
this
Point to the
-
Its type:
- Global execution context
- Function execution context
eval
Execution context
-
Code execution process:
- Creating a Global Context (Global EC)
- Global execution context
(caller)
Line by line, top-down. When a function is encountered, the function execution context(callee)
被push
To the top of the execution stack - The function execution context is activated as active EC, which starts executing the code in the function,
caller
suspended - After the function is executed,
callee
被pop
Remove execution stack and return control to the global context(caller)
, continue to execute
DOM
1. Dom manipulation
Create:
CreateDocumentFragment () // Create a DOM fragment createElement() // Create a specific element createTextNode() // create a text nodeCopy the code
-
Add: the appendChild ()
-
Remove: removeChild ()
-
Replacement: the replaceChild ()
-
Insert: the insertBefore ()
-
Copy: cloneNode (true)
Looking for:
GetElementsByTagName () // By the tag Name getElementsByClassName() // by the tag Name getElementsByName() // by the value of the element's Name attribute getElementById() // By element Id, uniquenessCopy the code
Child nodes
Node.childNodes
// Get the list of child nodes NodeList; Note that the newline counts as a text node in the browser, and you need to filter if you get the node list this wayNode.firstChild
// Returns the first child nodeNode.lastChild
// Returns the last child
The parent node
Node.parentNode
// Returns the parent nodeNode.ownerDocument
// return the ancestor node (entire document)
Sibling node
Node.previousSibling
// Returns the previous node, or null if notNode.nextSibling
// Returns the latter node
2. Dom events
3. Dom event model
The DOM event model is divided into capture and bubbling. Propagation between child elements and parent elements after an event occurs. This spread is divided into three stages.
- (1) Capture stage: events from
window
objectFrom top to bottomPhase of target node propagation; - (2) Target stage: the stage when the real target node is processing events;
- (3) Bubbling stage: events from
The target
nodeFrom the bottom uptowindow
Phase of object propagation.
The third parameter to addEventListener, as described above, specifies whether the event is executed in the capture or bubble phase. True means the event is executed in the capture phase, and false means the event is executed in the bubble phase. So what is event bubbling and event capture? It can be explained by the following picture:
3.1. Event capture
Capturing works from top to bottom. The event goes from the Window object, then to the Document (object), then to the HTML tag (get the HTML tag from the Document.documentElement), then to the body tag (get the body tag from the document.body), Then follow the normal HTML structure of the layer down, and finally reach the target element. We just need to change the third parameter of addEventListener to true to achieve event capture.
The code is as follows:
// From Xyyojl's Insight into DOM event mechanics <! <style> body{margin: 0; } div{border: 1px solid# 000; }
#grandfather1{width: 200px; height: 200px; }
#parent1{width: 100px; height: 100px; margin: 0 auto; }
#child1{width: 50px; height: 50px; margin: 0 auto; }</style> <! <div id="grandfather1"> <div id="parent1"> parent <div id="child1"</div> </div> <! <script> var grandfather1 = document.getelementbyid ('grandfather1'),
parent1 = document.getElementById('parent1'),
child1 = document.getElementById('child1');
grandfather1.addEventListener('click'.function fn1(){
console.log('grandfather');
},true)
parent1.addEventListener('click'.function fn1(){
console.log('daddy');
},true)
child1.addEventListener('click'.function fn1(){
console.log('son');
},trueFn1 fn2 fn3 fn1 fn2 fn3 // fn1 fn2 fn3 or fn3 fn2 fn1 </script>Copy the code
3.2. Event bubbling
An event bubble is an event that bubbles up from where it started. We only need to change the third parameter of addEventListener to false to implement event bubbling.
The code is as follows:
Var grandfather1 = document.getelementbyid ('grandfather1'),
parent1 = document.getElementById('parent1'),
child1 = document.getElementById('child1');
grandfather1.addEventListener('click'.function fn1(){
console.log('grandfather');
},false)
parent1.addEventListener('click'.function fn1(){
console.log('daddy');
},false)
child1.addEventListener('click'.function fn1(){
console.log('son');
},falseFn1 fn2 fn3 fn1 fn2 fn3 fn1 fn2 fn3 fn1 fn2 fn3 fn1 fn2 fn3 fn1 fn2 fn3 // fn1 fn2 fn3 or fn3 fn2 fn1Copy the code
4. Event Agent (Event Delegate)
Since events propagate up to the parent node during the bubbling phase, you can define the listener function of the child node on the parent node and let the listener function of the parent node process events of multiple child elements uniformly. This approach is called delegation of events.
Advantages of 4.1.
- Reduce memory consumption and improve performance
If you bind a function to each list item, it is very expensive in memory and requires a lot of performance in terms of efficiency. Using event agent, we only need to give the parent container ul binding approach, so no matter which a descendant elements, click will be according to the transmission mechanism of transmission of bubbling, click behavior triggers the container, and then the corresponding method to carry out, according to the event source, we can know is who, click to do different things.
- Dynamically bound events
By user operation in many cases, we need to dynamically add or delete a list item element, if give each child element binding events at the beginning, then in the list of changes, just need to give new elements of the binding event, to tie events is about to delete the elements of the solution, if use event agency will save a lot of trouble.
4.2. Event handling across browsers
Standard event objects:
- (1)
type
: Event type - (2)
target
: Event target - (3)
stopPropagation()
Method: Prevent events from bubbling - (4)
preventDefault()
Method: Block the default behavior of the event
Event objects in IE:
-
(1) Type: indicates the event type
-
(2)srcElement: event target
-
(3)cancelBubble property: Prevent event bubbling true means prevent bubbling, false means do not prevent bubbling
-
(4)returnValue property: prevents the default behavior of the event
Var eventUtil{/* add event handler */ addHandler:function(element,typeHandler){// Parameter list element, event type, functionif(element.adDeventListener){//DOM 2 level event handler element.addeventListener (type,handler,false); //falseTable bubbling event call;trueTable capture event call}else if(element.attachevent){//IE event handler element.attachevent ('on'+type,handler); // The reason there is no third argument is that IE8 and earlier browsers only support event bubbling}else{//DOM 0 level event handler element['on'+type]=handler; }}, /* Remove event handler */ removeHandler:function(element,typeHandler){// Remove event handler, parameter list element, event type, functionif(element. RemoveEventListener) {/ / DOM level 2 event handler element. The removeEventListener (type,handler,false); //falseTable bubbling event call;trueTable capture event call}else if(element.detachevent){//IE event handler element.detachevent ('on'+type,handler); // The reason there is no third argument is that IE8 and earlier browsers only support event bubbling}else{//DOM 0 level event handler element['on'+type]=null;
}
},
getEvent:function(event){
returnevent? event:window.event; }, getTarget:function(event){
return target || srcElement;
},
stopPro:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
},
preventDef:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false; }}},Copy the code
JS intermediate article
1. Lazy loading and preloading of images
- Preloading: Images are loaded ahead of time and rendered directly from the local cache when the user needs to view them. Why use preloading: Load some of the main content of a web page before it loads to provide a better user experience and reduce wait time. Otherwise, if the content of a page is too large, there will be white space.
Solutions to page white space:
-
1). Preloading
-
2). Use SVG station images to quickly build up some structures and replace the current placeholders when the requested data arrives
The method of preloading is as follows: 1. Use HTML tag 2. Use Image object 3. Use XMLHTTPRequest objects, but finely control the preloading processCopy the code
- Lazy loading: The main purpose of lazy loading is to serve as a front-end optimization for the server, reducing the number of requests or delayed requests.
The essence of two technologies: the behavior of both is opposite, one is early loading, one is slow or even not loading. Lazy loading relieves the pressure on the front end of the server, while preloading increases it.
2, lazy loading how to achieve
- Scenario: There are many images on a page, but only a few images appear on the first screen. In this case, loading all images at once will affect performance. This can be done using lazy loading, where the page scrolls to the visual area before loading. Optimized the first screen loading.
- Implementation:
img
The labelsrc
Property is empty, give onedata-xx
Property, which holds the real address of the image. When the page scrolls until the image appears in the visible area, use js to fetch the imagedata-xx
The value is assigned tosrc
. - Advantages: Fast page loading, reduces server pressure, saves traffic, and provides good user experience.
3. The way to obtain the width and height of JS
To obtain the height and width of the screen (screen resolution) : window. The screen. The height/widthCopy the code
Access to the working area of the screen height and width (remove the status bar) : window. Screen. AvailHeight/availWidthCopy the code
Web page full height and Width: the document body. ScrollHeight/WidthCopy the code
Scroll bar roll up to the height and the width of the roll to the right: the document. The body. The scrollTop/scrollLeftCopy the code
Web page visible region of the height and width (without border) : document. Body. ClientHeight/clientWidthCopy the code
Web page visible region of the height and width (line) : document. Body. OffsetHeight/offsetWidthCopy the code
4. Implementation of JS drag function
The first three events are mousedown, Mousemove, and mouseup. When the mouse is clicked and pressed, you need a tag to indicate that the mouse has been pressed, and you can execute the specific method in mousemove.
ClientX, clientY refers to the coordinates of the mouse, marking abscis and ordinate respectively, and we use offsetX and offsetY to represent the initial coordinates of the element. The example of movement should be: the coordinates when the mouse moves – the coordinates when the mouse is down.
In other words, the positioning information is:
-
Mouse movement coordinates – mouse down coordinates + element initial offetLeft.
-
There is another thing that is also rational, that is, drag and drop is absolute positioning at the same time. What we change is the equivalence of left and top under absolute positioning condition.
5, asynchronous loading JS method
-
If your script does not change the content of the document, you can add the defer attribute to the script tag to speed up the processing of the document. Because the browser knows that it will be able to safely read the rest of the document without executing the script, it will delay the interpretation of the script until the document has been displayed to the user.
-
The async, HTML5 attribute only applies to external scripts, and if in IE both defer and Async exist, defer takes precedence and the script executes when the page is complete.
-
Create a script tag and insert it into the DOM
Garbage collection mechanism in JS
-
JS has an automatic garbage collection mechanism
-
JS memory life cycle (life of variables)
- 1). Allocate the space you need var a = 20
- 2). Alert (a + 10)
- 3). When not applicable, free the memory space a = null
-
The JS garbage collector performs a free operation at regular intervals, generally through the tag cleanup algorithm
Tag cleanup algorithm: the most common garbage collection method of JS. When a variable enters the execution environment, such as declaring a variable in a function, the garbage collector marks it as'Enter the environment', when the variable leaves (after the function has finished executing), it is marked as'Leave the environment'. The garbage collector marks all variables stored in memory at run time and then removes variables in the environment and variables referenced by that variable in the environment (closures). The variables that remain marked after this is done are the ones to be deletedCopy the code
7. Memory leaks
- Unexpected global variable: cannot be reclaimed
- Timer: Not properly turned off, so referenced external variables cannot be released
- Event listening: Not properly destroyed (may occur in earlier browsers)
- Closures: Causes variables in the parent to be unable to be released
dom
References: When a DOM element is deleted, the reference in memory is not cleared correctly
8, shake and throttle
The anti-shake and throttling function is one of the most commonly used high-frequency trigger optimization methods, which can greatly help performance.
8.1, stabilization,
-
Definition: merges events and does not trigger events. Events are triggered only when the event has not been triggered for a certain period of time.
-
Principle: Delay the operation of the processing function. If the event is triggered again before the set delay comes, the last delay operation timer will be cleared and the timer will be reset.
-
Scenario: Verify the user name in a KeyDown event. If the user enters the user name, enter the user name again and verify the input.
function debounce(fn, wait, immediate) {
let timer = null
return function() {
let args = arguments
let context = this
if(immediate && ! timer) { fn.apply(context, args) }if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(context, args)
}, wait)}}Copy the code
8.2, throttling
-
Definition: When an event is continuously fired, the event is merged within a certain period of time, and then the event is actually fired after a certain interval of time. Trigger at intervals.
-
Principle: Delay the operation of the processing function. If the event is triggered again before the set delay comes, the last delay operation timer will be cleared and the timer will be reset.
-
Scenario: When resize changes the layout, onScroll loads the image below.
-
Implementation:
Method 1: Use a timestamp.
When the event is triggered, we take the current timestamp, subtract the previous timestamp (initially set to 0), execute if it is greater than the period set, and then update the timestamp to the current timestamp. If it is less than the current timestamp, we do not execute.
Bug: The first event is executed immediately, there is no way to activate the event after the event is stopped.
function throttle(fn, interval) {
var previousTime = +new Date()
return function () {
var that = this
var args = arguments
var now = +new Date()
if (now - previousTime >= interval) {
previousTime = now
fn.apply(that, args)
}
}
}
Copy the code
Method 2: Use a timer
When the event is triggered, we set a timer, and when the event is triggered, if the timer exists, it is not executed until the timer is executed, and then the function is executed to clear the timer so that the next timer can be set.
Bug: The first event will be executed after n seconds, and the event will still be executed after the trigger is stopped.
function throttle(fn, interval) {
var timer
return function (){
var that = this
var args = arguments
if(! timer){ timer =setTimeout(function () {
fn.apply(that, args)
timer = null
}, interval)
}
}
}
Copy the code
Method three: optimization
Mouse over can be executed immediately, and can be executed again when the trigger is stopped.
var throttle = function(func,delay){
var timer = null;
var startTime = Date.now();
return function(){
var curTime = Date.now();
var remaining = delay-(curTime-startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if(remaining<=0){
func.apply(context,args);
startTime = Date.now();
}else{
timer = setTimeout(func,remaining); }}}Copy the code
9. Currization of functions
The technique of filling in a function with several arguments and then returning a new function is called currization of the function.
It is usually used to prespecify generic parameters for a function for multiple calls without intruding on the function.
const add = function add(x) {
return function (y) {
return x + y
}
}
const add1 = add(1)
add1(2) === 3
add1(20) === 21
Copy the code
What is a higher-order function? How to write a higher-order function
Higher-order function a higher-order function is a function that meets at least one of the following conditions:
- Takes one or more functions as input
- Output a function
That is, higher-order functions are functions that operate on other functions, either passing them as arguments or returning them.
Simply put, a higher-order function is a function that either receives a function as an argument or outputs a function as a return value.
Higher-order functions: parameter values are functions or return values are functions. For example, map, Reduce, filter, and sort methods are higher-order functions.
To write a higher-order function is to make its arguments accept other functions.
10.1 the map () method
The map() method creates a new array. The result is the result returned by each element in the array calling a provided function, leaving the original array unchanged. The callback passed to map takes three arguments, namely
CurrentValue, index (optional), array (optional), and in addition to callback can accept this (optional), which is used when the callback function is executed.Copy the code
Taking a simple example, we now have an array [1, 2, 3, 4] and we want to generate a new array with each element twice as many as the previous array. We can do this in two ways, with and without higher-order functions.
// const arr1 = [1, 2, 3, 4]; const arr2 = arr1.map(item => item * 2); console.log( arr2 ); // [2, 4, 6, 8] console.log( arr1 ); // [1, 2, 3, 4]Copy the code
10.2. Filter () method
The filter() method creates a new array that contains all the elements of the test implemented by providing the function, leaving the original array unchanged. The parameters received are the same as the map, and the return value is a new array of all the elements that passed the test, or an empty array if none of the array elements passed the test.
As an example, we now have an array [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4] and we want to generate a new array that has no duplicates, i.e. de-duplicates.
const arr1 = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
const arr2 = arr1.filter( (element, index, self) => {
returnself.indexOf( element ) === index; }); console.log( arr2 ); // [1, 2, 3, 5, 4] console.log( arr1 ); // [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4]Copy the code
10.3 reduce() method
The reduce() method performs a provided Reducer function (ascending execution) on each element in the array, summarizing its results into a single return value.
The reduce callback function (callback) accepts four parameters: accumulator, currentValue, currentIndex (optional), array (optional). In addition to callback, you can also accept the initialValue initialValue (optional).Copy the code
-
If no initialValue is provided, then accumulator uses the first element in the array when the callback function is called the first time, and currentValue is the second element in the array. Calling reduce on an empty array with no initial value will report an error.
-
If initialValue is provided, it will be the value of the first parameter when the callback function is called for the first time, which is accumulator. CurrentValue uses the first element in the original array.
Let’s take a simple example. We now have an array [0, 1, 2, 3, 4], and need to calculate the sum of the elements of the array.
Without the initialValue value
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
returnaccumulator + currentValue; }); console.log( sum ); // 10 console.log( arr ); // [0, 1, 2, 3, 4] The above is the case with no initialValue.Copy the code
Have the initialValue values
Let’s look at the case where we have an initialValue, let’s say initialValue is 10, and let’s look at the code.
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
returnaccumulator + currentValue; }, 10); console.log( sum ); // 20 console.log( arr ); // [0, 1, 2, 3, 4]Copy the code
Examples:
Known as an array: var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10]. Write a program to flatten and divide an array of duplicate data, resulting in an ascending and non-repeating array
The answer:
Var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10] / / flatletFlatArr = arr.flat(4) // De-weightletDisArr = array. from(new Set(flatArr)) // Sortlet result = disArr.sort(function(a, b) {
return a-b
})
console.log(result)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Copy the code
11, Web Worker
The multithreaded environment created by modern browsers for JavaScript. Some tasks can be created and assigned to worker threads for parallel running. The two threads can run independently without interference and communicate with each other through their own message mechanism.
// create worker const worker = new worker ('work.js'); // Push worker.postMessage('Hello World'); // Listen for worker.onmessage =function (event) {
console.log('Received message ' + event.data);
}
Copy the code
-
Limitations:
- The same-origin restrictions
- Document/window/alert/confirm cannot be used
- Unable to load local resources
12. How to convert ES6 to ES5, and how does Babel work
- Parsing: Parsing code strings into abstract syntax trees
- Transform: Transforms the abstract syntax tree
- Rebuild: Regenerate code strings from the transformed abstract syntax tree
13. What design patterns have been used
(1) Singleton mode
-
Definition: Ensures that a class has only one instance and provides a global access point to access it.
-
If the instance exists, return it directly. If it does not exist, create it and return it. This ensures that a class has only one instance object.
-
Application scenario: A single object. For example, popovers should only be created once, no matter how many times they are clicked.
(2) Publish/subscribe
-
Definition: Also known as the observer pattern, it defines a one-to-many dependency between objects. When an object’s state changes, all dependent objects are notified.
-
Scenario: Subscribe to columns and public accounts of interest.
(3) Strategy mode
-
Definition: Encapsulate an algorithm (solution) in a policy class.
-
Advantages:
- The policy pattern avoids multiple judgment criteria in code.
- The strategy pattern well embodies the open-closed principle and encapsulates each algorithm (solution) in a strategy class. Easy to switch, understand, and expand.
- The various algorithms in the policy can be reused in various parts of the system, avoiding copy and paste.
- Policy mode adds more or less policy classes to the program. But it’s clearer than stacking it up in business logic.
- In violation of the minimum knowledge principle, you must understand various policy classes to better apply them in business.
-
Application scenario: calculate different bonus according to different employee performance; Multiple validation rules in form validation.
(4) Agent mode
-
Definition: Provides a proxy or placeholder for an object to control access to it.
-
Application scenario: Lazy loading of images (Loading an image asynchronously by loading a loading image, and then loading the completed image into the IMG tag.)
(5) Intermediary model
-
Definition: A mediator object through which all other related objects communicate, rather than referring to each other, simply notifies the mediator object when one of them changes. You can remove the tight coupling between objects.
-
Application scenario: For example, if there is a shopping cart demand, there is an item selection form, a color selection form, a purchase quantity form, etc., all these events will trigger the change event. Then, these events can be forwarded and processed through the intermediary to realize the decoupling between events, and only the intermediary object can be maintained.
(6) Decorator mode
-
Definition: to dynamically add methods to an object while the program is running without changing the object itself.
-
Application scenarios: Some methods remain unchanged, but other methods are mounted on the original method to meet existing requirements. Function decoupling, the function is divided into multiple reusable functions, and then the separated function is mounted to a function, to achieve the same effect but enhance the reuse.
14. Event queue (macro task, micro task)
This time, understand the JavaScript execution mechanism thoroughly
15, how to use native JS to achieve a rotation map, and scrolling
Ideas, with timer to achieve, and how to achieve smooth rolling effect. See: native JS implementation of the wheel cast diagram
Front-end modularization
Front-end modularization is a complex file programming a separate module, such as JS files, etc., divided into separate modules for reuse (reuse) and maintenance (version iteration), which leads to the problem of interdependence between modules, so there are commonJS specifications, AMD, CMD specifications, etc., And a tool for JS packaging (compilation, etc.) called Webpack.
What is a module?
Encapsulate a complex program into several blocks (files) according to certain rules (specifications), and combine them together. The internal data and implementation of the block are private, and only some interfaces (methods) are exposed to the outside to communicate with other external modules
2. The evolution of modularity
1) Global function mode: encapsulate different functions into different global functions
-
Encoding: Encapsulating different functions into different global functions
-
Problem: Contaminate the global namespace, causing naming conflicts or data insecurity, and no direct relationship between module members
2) Namespace mode: encapsulate simple objects
-
Purpose: Reduces global variables and resolves naming conflicts
-
Problem: Data is not secure (external data can be directly modified inside the module)
3) IIFE mode: anonymous function call (closure)
-
What it does: Data is private and can only be manipulated externally by exposed methods
-
Encoding: Encapsulates data and behavior inside a function, exposing the interface by adding properties to the window
-
Question: What if the current module depends on another module?
-
Solution: IIFE schema enhancement: introduce dependencies
3. Benefits of modularity
- Avoiding naming conflicts (reducing namespace pollution)
- Better separation, load on demand
- Higher reusability
- High maintainability
4. There are problems with the introduction of multiple script tags
Request too much
First we rely on multiple modules, which will send multiple requests, resulting in too many requestsCopy the code
Relying on the fuzzy
We don't know what their dependencies are, which means it's easy to get the load sequencing wrong because you don't know what their dependencies are.Copy the code
Difficult to maintain
The above two reasons lead to difficult maintenance, and it is likely to affect the whole situation, leading to serious problems in the project.Copy the code
Modularity certainly has several benefits, however, a page needs to introduce multiple JS files, will occur these problems. These issues can be addressed through modular specifications. The commonJS, AMD, ES6, CMD specifications that are most popular in development are described below.
5. Modular specification
CommonJS
The specification is mainly used for server-side programming, loading modules are synchronous, this is not suitable in the browser environment, because synchronization means blocking loading, browser resources are loaded asynchronously, so there areAMD CMD
Solutions.
AMD
The specification loads modules asynchronously in a browser environment, and multiple modules can be loaded in parallel. However,AMD
Specification development costs are high, code is difficult to read and write, and semantics are not smooth in the way modules are defined.
CMD
The specification andAMD
The specification is similar in that it is used for browser programming, relies on proximity, deferred execution, and can be easily implemented inNode.js
In the running. However, depending on SPM packaging, the loading logic of modules is biased
ES6
On the level of language standards, module functions are realized, and the implementation is quite simple and can be replaced completelyCommonJS
和AMD
Specification, become a common browser and server module solution.
-
Distinction between require and import
require
Support dynamic import,import
Not supported, under proposal (supported under Babel)require
It’s synchronous import,import
Asynchronous importrequire
If the value is copied, the change of the exported value does not affect the imported value.import
Points to a memory address, and the import value changes with the export value
6. Differences between MVC and MVVM
Model
Data used to encapsulate and process data related to the application’s business logic;View
As the view layer, it is mainly responsible for data display;Controller
Defines how the user interface responds to user input, connects models and views, and is used to control the flow of the application and handle changes in user behavior and data.
MVC encapsulates the response mechanism in the Controller object. When the user interacts with your application, the event trigger in the controller starts working.
MVVM automates the synchronization logic between View and Model. The Controller’s View and Model synchronization is no longer handled manually, but is handled by the data binding function provided by the framework. It only needs to tell it which part of the Model the data displayed by the View corresponds to. Two-way data binding, which means that changes in the View can change the Model in real time, and changes in the Model can be updated to the View in real time.
Reference: Simple analysis of MVC/MVP/MVVM model in front-end development
7. Advantages and disadvantages of async and await
Compared with using Promise directly, async and await have the advantage of processing then call chain and writing code more clearly and accurately.
The disadvantage is that abusing await can cause performance problems because await blocks code, and perhaps subsequent asynchronous code does not depend on the former but still needs to wait for the former to complete, causing the code to lose concurrency.
Let’s look at a code that uses await.
var a = 0
var b = async () => {
a = a + await 10
console.log('2', a) // -> '2' 10
a = (await 10) + a
console.log('3', a) // -> '3' 20
}
b()
a++
console.log('1', a) // -> '1' 1
Copy the code
First function b, before execution to await 10 variable a is zero, because await inside the generators, generators will be kept on the stack, so this time a = 0 is preserved
Since await is an asynchronous operation, it immediately returns a Promise object in a pending state to temporarily return control of executing code so that the code outside the function can continue execution. Console. log(‘1’, a) is executed first.
So the synchronous code is done, the asynchronous code is executed, the saved value is taken out and used, so a is equal to 10 and then the regular execution code is followed
Recommendation:
Detailed description of the front modular of the Boat in the waves (Full version)
Subwaydown’s front-end modularity: CommonJS,AMD,CMD,ES6
6. Front-end packaging tools
1) Task-based tools:
Grunt, GulpCopy the code
They automatically perform assigned tasks, like an assembly line, putting resources on it and processing them through different plug-ins, they have active communities, rich plug-ins, and they make it easy to create various workflows.
2) Tools based on modular packaging:
Browserify, Webpack, rollup.jsCopy the code
Node.js development experience should be familiar with modules, need to reference components directly a require IS OK, this kind of tool is this mode, can also achieve on demand, asynchronous loading module.
3) Integrated tools:
Yeoman, FIS, JDF, Athena, Cooking, WeflowCopy the code
Scaffolding tools that use multiple technology stacks have the advantage of being out-of-the-box, but the disadvantage is that they constrain technology selection and are relatively expensive to learn.
7, webpack
WebPack is a module packaging tool. You can use WebPack to manage your module dependencies and compile the static files required by the output modules. It can well manage and package HTML, JavaScript, CSS and various static files (images, fonts, etc.) used in Web development, making the development process more efficient. Webpack has module loaders for different types of resources. The WebPack module packer analyzes the dependencies between modules and generates optimized and merged static resources.
Webpack features two major features:
-
1. Code Splitting (can be done automatically)
-
2. Loader can process various types of static files and supports serial operations
Webpack scripts are written in commonJS format, but AMD/CMD support is also comprehensive, making it easy to migrate code from older projects.
Webpack has requireJs and Browserify features, but it still has a lot of new features of its own:
- right
CommonJS
、AMD
、ES6
The syntax is made compatible
- right
js
,css
, images and other resource files support packaging
- Tandem module loaders and plug-in mechanisms, so that it has better flexibility and extensibility, such as provide
The CoffeeScript
,ES6
The support of
- There are separate configuration files
webpack.config.js
- You can cut the code into different ones
chunk
, to achieve on-demand loading, reduce the initialization time
- support
SourceUrls
和SourceMaps
, easy to debug
- Have a powerful
Plugin
Interfaces, mostly internal plug-ins, are flexible to use
webpack
Using asynchronousIO
And it has multi-level cache. This makes thewebpack
Faster and faster on incremental compilation
8. How does Webpack optimize packaging
From extracting common modules, distinguishing the development environment, removing redundant CSS and JS files and so on.
Recommended arlendp2012 article Webpack optimization
9, Webpack packaging principle
-
Initialization: start build, read and merge configuration parameters, load Plugin, instantiate Compiler.
-
Compilation: issued from Entry, the corresponding Loader is successively called for each Module to translate the file content, and then the Module depends on the Module is found, and the compilation process is carried out recursively.
-
Output: Combine compiled modules into chunks, convert chunks into files, and output them to the file system.
Recommended whjin article webpack principle
10. What webPack does
- Dependency management: it facilitates the reference of third-party modules, makes modules easier to reuse, avoids conflicts caused by global injection, and avoids reloading or loading unnecessary modules. Read dependent modules layer by layer, adding different entries; At the same time, dependent modules are not repackaged.
- Merge code: bundle various discrete modules into a large file, reduce
HTTP
Number of request links, matchUglifyJS
Reduce and optimize the size of your code.- Plugins: Unified processing of imported plugins,
babel
compileES6
File,TypeScript
.eslint
You can check for compile-time errors.
In a word: Webpack is all about dependencies, modularization, packaging zip files, and managing plug-ins.
Reference article:
Brush the words of front end face test questions, collect this one is enough!
Nuggets Daily Quality articles collection for the second half of 2017: The front end
2018 for the front end of the interview: through fine alignment (fine) | the nuggets technical essay
“Intermediate and advanced front-end interview” JavaScript handwritten code unbeatable secrets