preface

In the previous part, we summarized the basic knowledge of JavaScript, while this part is about the characteristics of this language, which is also its core knowledge and interview focus.

function

Functions can be described as first-class citizens in JavaScript, and there are quite a lot of concepts involved in functions. At the beginning, I was confused when I just learned them. Here is a question to start the summary and learning of functions.

How do I execute a piece of JavaScript code

The execution of JavaScript code is divided into the following three steps:

  • Analyze for lexical and grammatical errors
  • Precompilation – occurs just before the function is executed, generating the variable environment, lexical environment
  • Explain to perform

One of the things that makes JavaScript special is when it’s precompiled, so let’s focus on what’s going on in precompiled.

precompiled

The engine starts by creating an execution context (also called an Activation Object or an AO Object). There are three main types of execution contexts:

  • Global execution context: Only one
  • Function execution contexts: There are an infinite number of them, one for each function called
  • EvalExecution context:evalFunction code to run in, rarely used

The creation of execution context can be divided into creation phase and execution phase

Create a stage

1. Bind this to

2. Create a lexical environment

3. Generate a variable environment

The lexical environment and variable environment are explained here, but they are almost identical components. The lexical environment consists of two parts, one is the location where variables and function declarations are stored, and the other is the reference to the external environment.

The pseudocode is as follows:

GlobalExectionContext = {  // Global execution context
  LexicalEnvironment: {    	  // lexical context
    EnvironmentRecord: {   		// Environment record
      Type: "Object".// Global environment
      // The identifier is bound here
      outer: <null>, // A reference to the external environment
    }  	   		  
  }  
}

FunctionExectionContext = { // Function execution context
  LexicalEnvironment: {  	  // lexical context
    EnvironmentRecord: {  		// Environment record
      Type: "Declarative".// Function environment
      // The identifier is bound here // a reference to the external environment
      outer: <Global or outer function environment reference>}}Copy the code

The variable environment is also a lexical environment. The difference between lexical environment and variable environment is:

  • The lexical environment stores function declarations and bindingsletconstvariable
  • The variable environment is bound onlyvarvariable

Execution phase

Complete the allocation of all variables, and finally execute the code

Scope & scope chain

Each JavaScript function is an object, and some properties of the object are accessible and some are not, and these properties are only accessible to the JavaScript engine, such as [[scope]].

[[scope]] is the scope of a function that stores the collection of execution contexts.

[[scope]] is a collection of execution context objects stored in [[scope]. This collection is linked in a chain called the scope chain. When looking for variables, start at the top of the scope chain. When a variable is not found in the current execution context, it looks up in references to the external environment, rendering a chain structure.

Scope and variable declaration enhancements

  • inJavaScriptIn, function declarations and variable declarations will beJavaScriptThe engine implicitly promotes to the top of the current scope
  • The assignment part of the declaration statement is not promoted, only the name
  • Function declarations take precedence over variables. If the variable name is the same as the function name and no value is assigned, the function declaration overrides the variable declaration
  • If a function has multiple arguments with the same name, the last argument (even if undefined) overrides the previous one

closure

When an internal function is saved externally, a closure is generated. After the closure is generated, the inner function can still access the variables of the outer function in which it is located.

When the function executes, the execution context is created and the scope chain (which stores all execution contexts that the function can access) is retrieved. When the function is executed, the corresponding execution context is unique. When the function is executed, the function will lose reference to the scope chain. JS garbage collection mechanism adopts reference counting strategy, if a piece of memory is no longer referenced, the memory will be released.

However, when the closure exists, that is, when the inner function retains a reference to the external variable, the scope chain is not destroyed, and the inner function can still access the variables of the external function, which is the closure.

That is, closures escape GC policy, so misuse leads to a memory leak, which is itself a memory leak?

Classic topic

for (var i = 0; i < 5; i++) {
  setTimeout(function timer() {
    console.log(i)
  }, i * 100)}Copy the code
function test() {
   var a = [];
   for (var i = 0; i < 5; i++) {
         a[i] = function () {
            console.log(i); }}return a;
}

var myArr = test();
for(var j=0; j<5; j++) { myArr[j](); }Copy the code

Both examples print five 5’s. The simple explanation is that variable I records the value that finally breaks out of the loop, namely 5, which can be solved by executing the function or let immediately. Because the execute now function creates a new execution context that can hold the value of the current loop I, let builds block-level scopes that can also hold the value of the current loop I.

for (var i = 0; i < 5; i++) { ; (function(i) {
      setTimeout(function timer() {
         console.log(i)
      }, i * 100)
   })(i)
}
Copy the code
function test(){
   var arr=[];
   for(i=0; i<10; i++) { (function(j){
         arr[j]=function(){
         console.log(j);
         }
      })(i)
   }
   return arr;
}

var myArr=test();
for(j=0; j<10; j++) { myArr[j](); }Copy the code

Encapsulating private variables

function Counter() {
   let count = 0;
   this.plus = function () {
      return ++count;
   }
   this.minus = function () {
      return --count;
   }
   this.getCount = function () {
      returncount; }}const counter = new Counter();
counter.puls();
counter.puls();
console.log(counter.getCount())
Copy the code

counter

Implementing a foo function can be used like this:

a = foo();
b = foo();
c = foo();
// a === 1; b === 2; c === 3;foo.clear(); d = foo();//d === 1;
Copy the code
function myIndex() {
    var index = 1;

    function foo(){
        return index++;
    }

    foo.clear = function() {
        index = 1;
    }
    return foo;
}

var foo = myIndex();
Copy the code

How do you call a function in JavaScript?

There are several ways to call a function in JavaScript

  • Method invocation patternFoo.foo(arg1, arg2) ;
  • Function call patternfoo(arg1, arg2);
  • Constructor invoke pattern(new Foo())(arg1, arg2);
  • call / applyInvocation patternFoo.foo.call(that, arg1, arg2);
  • bindInvocation patternFoo.foo.bind(that)(arg1, arg2)();

If the throttle

Whether it is interview or business development, this is frequently encountered knowledge, let’s take a look

Stabilization debounce

Function stabilization is when a function needs to be fired frequently and only executes once with enough free time.

Typical applications

  • Baidu search box in the input a little pause before updating recommended hot words.
  • Drag and drop
function debounce(handler, delay = 300){

  var timer = null;

  return function(){

    var _self = this,
        _args = arguments;

    clearTimeout(timer);
    timer = setTimeout(function(){
      handler.apply(_self, _args);
    }, delay);
  }
Copy the code
// If the timer is triggered frequently, clear the corresponding timer and start another timer. The timer is delayed for seconds
function debounce(handler, delay){

  delay = delay || 300;
  var timer = null;

  return function(){

    var _self = this,
        _args = arguments;

    clearTimeout(timer);
    timer = setTimeout(function(){ handler.apply(_self, _args); }, delay); }}// A function that you do not want to be called frequently
function add(counterName) {
  console.log(counterName + ":" + this.index ++);
}

// The required context object
let counter = {
  index: 0
}

// An auto-increment function for stabilization, binding the context object counter
let db_add = debounce(add, 10).bind(counter)

// Call the autoincrement function 3 times every 500ms, but only once in 3 times due to the anti-shake
setInterval(function() {
  db_add("someCounter1");
  db_add("someCounter2");
  db_add("someCounter3");
}, 500)


Somecounter3:0 Somecounter3:1 Somecounter3:2 Somecounter3:3 */
Copy the code

Throttling throttle

A function is executed only if it is longer than the execution period, and calls within that period are not executed. It’s like water droplets accumulate enough to trigger a fall.

Typical applications:

  • Grab coupons when crazy click, both to limit the number of times, but also to ensure that the first point first request
  • Window adjustment
  • Page scrolling
function throttle(fn,wait=300){
    var lastTime = 0
    return function(){
        var that = this,args=arguments
        var nowTime = new Date().getTime()
        if((nowTime-lastTime)>wait){
            fn.apply(that,args)
            lastTime = nowTime
        }
    }
}
Copy the code

this

When a function creates its execution context, the first step is to bind the reference to this. In JavaScript, the reference to this is determined when the function executes.

The directions of this are mainly as follows:

  1. Called directly as a function, in non-strict mode,thisPoint to thewindowIn strict mode,thisPoint to theundefined
  2. As a method call on an object,thisUsually points to the invoked object
  3. useapply,call,bindCan be boundthisPoint to the
  4. In the constructor,thisPoints to the newly created object
  5. There are no separate arrow functionsthisValue,thisBound when the arrow is created, it is the same context as the declaration

Where does this point when more than one “this” appears?

First, the new method takes precedence, followed by the bind method, followed by the obj.foo() method, followed by the foo method, and the arrow function’s this, once bound, can’t be changed in any way.

  1. newThe binding
  2. Explicit binding ->bind,apply,call
  3. Implicit binding ->obj.foo()
  4. Default binding -> Browser environment default iswindow

The default binding

function foo() { // In strict mode, this is bound to undefined
    "use strict";
    console.log( this.a );
}

var a = 2;

/ / call
foo(); // TypeError: Cannot read property 'a' of undefined

// --------------------------------------

function foo() { / / run
    console.log( this.a );
}

var a = 2;
foo()/ / 2
Copy the code

Implicit binding

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2.foo: foo
};

obj.foo(); / / 2
Copy the code

Note the following situation, called implicit loss.

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2.foo: foo
};

var bar = obj.foo; // Function alias

var a = "global"; // a is an attribute of the global object

bar(); // "global"
Copy the code

According to the binding

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2
};

foo.call( obj ); // 2 forces foo's this to be bound to obj when calling foo
Copy the code

The new binding

function foo(a) {
    this.a = a;
}

var bar = new foo(2); / / bar and foo (..) Call this to bind
console.log( bar.a ); / / 2
Copy the code

The interview of some factory

Please write down the answers to the following questions.

function Foo() {
    getName = function() {
        console.log(1);
    };
    return this;
}
Foo.getName = function() {
    console.log(2);
};
Foo.prototype.getName = function() {
    console.log(3);
};
var getName = function() {
    console.log(4);
};

function getName() {
    console.log(5);
}

// Write the following output:
Foo.getName();      //-> 2 getName() on Foo, it won't be 3, because only instances of Foo will be 3, and Foo doesn't have a 3
getName();          //-> 4 window getName, console.log(5) is promoted and reassigned in console.log(4)
Foo().getName();    //-> 1 In Foo, getName is the global getName, overwriting and printing 1
getName();          //-> 1 window getName();
new Foo.getName();  //-> 2 Foo is preceded by a '.' without parentheses, so Foo. GetName is used as the constructor
new Foo().getName();//-> 3 is an instance of Foo, and the prototype will print 3
Copy the code

This in the arrow function

This in the arrow function inherits this from its scope parent, that is, the this at which the arrow function is declared

let a = {
  b: function() {
    console.log(this)},c: () = > {
    console.log(this)
  }
}

a.b()   // a
a.c()   // window

let d = a.b
d()     // window
Copy the code

Bind, apply implementation

Since the encapsulationbindmethods

  • becausebindBind (an object,… Residual parameters)
    • So you need to program on function.prototype
  • Uses an object of the passed argument and the rest of the argumentapplyIs executed in a callback function
  • To get the bound function at the first levelthisBecause I want to get that functionapply
/** * Simple version */
Function.prototype.myBind = (that, ... args) = > {
  const funcThis = this;
  return function(. _args) {
    returnfuncThis.apply(that, args.concat(_args)); }}Function.prototype.mybind = function(ctx) {
    var _this = this;
    var args = Array.prototype.slice.call(arguments.1);
    return function() {
        return _this.apply(ctx, args.concat(args, Array.prototype.slice.call(arguments)))}}Copy the code
/** * Self-wrapping bind method *@param  {object} Target [this object to which arguments are bound] *@return {[function]}  Return a new function that is bound to this
Function.prototype.myBind = function (target){
	target = target || window;
	var self = this;
	var args = [].slice.call(arguments.1);
	var temp = function(){};
	var F = function() {
    var _args = [].slice.call(arguments.0);
		return self.apply(this instanceof temp ? this: target, args.concat(_args));
	}
	temp.prototype = this.prototype;    // Maintain stereotype relationships when functions are constructors
	F.prototype = new temp();
	return F;
}
Copy the code

Self-encapsulate an Apply

  • The first thing to do is to prototypeFunction.prototypeOn the programming
  • You need to get a reference to the function, which in this case isthis
  • Let the passed object.fn =this
  • Execute the passed object.fn (passed parameter)
  • Return execution result
Function.prototype.myApply = function(context) {
  if (typeof this! = ='function') {
    throw new TypeError('Error')
  }
  context = context || window
  context.fn = this
  let result
  // There is a difference between processing parameters and call
  if (arguments[1]) { result = context.fn(... arguments[1])}else {
    result = context.fn()
  }
  delete context.fn
  return result
}
Copy the code

The new implementation

The process of new

  • Create a new object
  • Link to the prototype
  • The bindingthis
  • Return a new object
function create() {
    let obj = {}
    obj.__proto__ = con.prototype
    con.call(this)
    return obj
};
Copy the code

Prototype chain

  • JavaScripttheAll the objectsThere is a__proto__Property, which corresponds to the prototype of the object
  • JavaScriptFunction object except prototype__proto__In addition, it’s presetprototypeProperties (Function.prototype.bindThere is no)
  • When a function object is created as a constructor, itsprototypeProperty values will be used as prototypes for instance objects__proto__

constructor

Constructor returns a reference to the constructor when the instance object was created

function Parent(age) {
    this.age = age;
}

var p = new Parent(50);
p.constructor === Parent; // true
p.constructor === Object; // false
Copy the code

prototype

This is an explicit stereotype property that only functions have. Almost all functions have this property except function.prototype.bind ()

let fun = Function.prototype.bind()

If you create a function this way, you will notice that the function does not have the prototype attribute.

How did Prototype come about

This property is created automatically when we declare a function

function Foo(){}

And the value of this property is an object (that is, a stereotype) with only one property constructor

Constructor corresponds to the constructor, which is Foo

proto

This is an implicit stereotype property for every object, pointing to the stereotype of the constructor that created the object. This attribute actually points to [[prototype]], but [[prototype]] is internal and we can’t access it, so use __proto__.

In the new process, the new object is added __proto__ and linked to the constructor’s prototype.

Function.proto === Function.prototype

For an object,obj.__proto__. Constructor is the object’s constructor, but Function.__proto__=== function.prototype. Object. Prototype is also an Object, but this Object is not created by Object, but by the engine.

The engine creates Object.prototype, then function. prototype, and ties the two together with __proto__. Let fun = function.prototype.bind () has no prototype property. Because function. prototype is an object created by the engine, the engine doesn’t think it needs to add a Prototype attribute to this object.

So we can conclude that not all functions are created by new Function().

Function(); Function(); Function();

Function.__proto__ === function. prototype [prototype] Function() [prototype] Function() [prototype] Function() Function.__proto__ = Function. Prototype All other constructors can be found in the prototype chain, and Function Function() is essentially a Function. Function. Prototype = function. Prototype = function. Prototype = function. Prototype = function.

Prototype summary

  • ObjectIs the father of all objects. All objects can pass__proto__To find it
  • FunctionIs the father of all functions, all functions can pass__proto__To find it
  • Function.prototypeandObject.prototypeAre two special objects created by the engine
  • Except for the above two objects, all other objects are through the constructornewcreated
  • Function of theprototypeIt’s an object, which is a prototype
  • The object’s __proto__Pointing to the prototype,__proto__The prototype chain is formed by connecting objects and stereotypes

What is the mechanism of instanceof judging objects?

Check whether the __proto__ attribute of the instance object and the prototype constructor have a reference. If not, it will look up the object’s __proto__ until it is null.

const Person = function(){}
const p1 = new Person()
p1 instanceof Person//true

var str = 'hello world'
str instanceof String // true

var str1 = new String('hello world')
str1 instanceof String // true
Copy the code

Implement an Instanceof yourself

function instance_of(L, R) {
 var O = R.prototype;
 L = L.__proto__;
 while (true) {
   if (L === null)
     return false;// Return false if not found
   if (O === L)
     return true;// Return true for equality
   L = L.__proto__;// Continue looking up __proto__}}Copy the code

inheritance

The difference between classes

//ES5
function Animal(){
    this.name = 'Animal'
}
//ES6
class Animal2{
    constructor () {
        this.name = 'Animal'; }}Copy the code

Prototype chain inheritance

function Cat(){

}
Cat.prototype=new Animal()
var cat = new Cat()
Copy the code

How it works: Sets the prototype of a subclass directly to an instance of its parent class

Disadvantages: Because a subclass makes only one stereotype change, all instances of a subclass hold the value of the same parent class. When a value is modified on a subclass object, a new value is created on the instance if the value is of the original type being modified. But if it is a reference type, it will modify the reference type in the only instance of the parent class in the subclass, which will affect all subclass instances

Tectonic inheritance

function Cat(){
    Animal.call(this)}Copy the code

How it works: The subclass’s this is run through the parent class’s constructor

Disadvantages: Properties and methods on the Parent prototype chain are not inherited by subclasses

Examples of inheritance

function Cat(name){
    var instance = new Animal()
    instance.name = name || 'cat'
    return instance
}
Copy the code

Combination of inheritance

function Cat(){
    Animal.call(this)
}
Cat.prototype = new Animal()
Cat.prototype.constructor = Cat
Copy the code

Features:

  • To remedy the weakness of approach 2, you can inherit instance properties/methods as well as stereotype properties/methods
  • Both an instance of a subclass and an instance of a superclass
  • There is no reference property sharing problem
  • Can pass the cords
  • Function reuse

Disadvantages:

  • The parent constructor is called twice, generating two instances (the subclass instance hides the subclass prototype)

Copies of the inheritance

function Cat(name){
    var animal = new Animal();
    for(var p in animal){
        Cat.prototype[p] = animal[p];
    }
    Cat.prototype.name = name || 'Tom';
}
var cat = new Cat()
Copy the code

Features:

  • Support for multiple inheritance

Disadvantages:

  • Low efficiency and high memory footprint (due to copying parent class attributes)

Unable to get non-enumerable methods of the parent class (non-enumerable methods, not accessible using for in)

Parasitic combinatorial inheritance

function Cat(){
    Animal.call(this)} (function(){
    var Super = function(){}
    Super.prototype = Animal.prototype
    Cat.prototype = new Super()
})()
Cat.prototype.constructor = Cat
var cat = new Cat()
Copy the code

What is the difference between ES5/ES6 inheritance other than the way it is written?

  • Class declarations are promoted, but assignments are not initialized. Foo enters a temporary dead zone, similar to let, const declaration variables.
  • Class declares that strict mode is enabled internally.
  • All methods of class, including static and instance methods, are not enumerable.
  • All methods of class (static and instance methods) have no prototype object, so there is no [[construct]] to call with new.
  • Class must be called using new.
  • Class names cannot be overridden inside class.

Event loop

Why is JavaScript single threaded?

One of the hallmarks of the JavaScript language is single-threaded, which means you can only do one thing at a time. So why can’t JavaScript have multiple threads? It’s more efficient.

The single thread of JavaScript, relative to its purpose. As a browser scripting language, JavaScript’s primary purpose is to interact with users and manipulate the DOM. This means that it has to be single-threaded, which can cause complex synchronization problems. For example, if there are two threads of JavaScript at the same time, one thread adds content to a DOM node, and the other thread removes that node, which thread should the browser use?

So, to avoid complexity, JavaScript has been single-threaded since its inception, and this has been a core feature of the language and will not change.

In order to make use of the computing power of multi-core CPU, HTML5 proposes the Web Worker standard, which allows JavaScript scripts to create multiple threads, but the child threads are completely controlled by the main thread and cannot operate DOM. So, this new standard doesn’t change the single-threaded nature of JavaScript.

Event Loop

Do you know the Event Loop? – Ele. me front end

The nature of task queues

  • All synchronization tasks are executed on the main thread, forming an execution Context stack.
  • In addition to the main thread, there is a task queue. Whenever an asynchronous task has a result, an event is placed in the “task queue”.
  • Once all synchronization tasks in the execution stack are completed, the system reads the Task queue to see what events are in it. Those corresponding asynchronous tasks then end the wait state, enter the execution stack, and start executing.
  • The main thread repeats step 3 above.

Asynchronous tasks

  • setTimeOut,setInterval
  • DOMThe event
  • Promise

It can be divided into macro tasks and micro tasks as follows:

  • Macro tasks: setTimeout, setInterval, setImmediate, I/O(disk read/write or network communication), UI interaction events
  • Microtasks: process.nexttick, Promise.then

As we described earlier, an event loop places its asynchronous tasks in an event queue in the order in which they are executed. However, depending on the classification of asynchronous events, the event is actually sorted into the corresponding macro task queue or microtask queue.

When performing the task to empty stack, the main thread will check whether there is a task in the task queue, if any, will be small tasks in the queue tasks executed in sequence, until the task queue is empty, and then check whether there is a task in the macro task queue, if you have, take out the first macro task at a time to join the execution stack, then empty the execution stack, inspection tasks, And so on… .

How to implement asynchronous programming in JavaScript?

  • The callback function
  • Event listeners
  • Publish/subscribe
  • Promise object
  • Async function [ES7]

Comparison of setTimeOut, setImmediate, and Process.nexttick (

setTimeout()

An event is inserted into the event queue, and the main thread does not execute its specified callback until the current code (stack) completes execution. When the main thread time is too long, there is no guarantee that the callback will be executed at the time specified by the event. There will be a delay of 4ms for each setTimeout on the browser side. When multiple setTimeout is executed consecutively, the process may be blocked, resulting in performance problems.

setImmediate()

Events are inserted at the end of the event queue, and the main thread and event queue functions are executed immediately after completion. Similar to setTimeout(fn,0). Methods provided by the server node. The latest browser API has a similar implementation: Window.setimmediate, but few browsers support it.

process.nextTick()

Inserts to the end of the event queue, but executes before the next event queue. That is, the task it specifies always happens before all asynchronous tasks, at the end of the current main thread. General flow: at the end of the current stack — > before the next Event Loop — > trigger the callback specified by Process. The method provided by server-side Node. This approach can be used for problems with asynchronous delays. Can be interpreted as: not this time, the next appointment priority execution.

Promise

Promise itself is a synchronous execute now function. When resolve or reject is executed in executor, then/catch is executed asynchronously. When the main stack is complete, The resolve/ Reject method is invoked, and when p is printed, it returns a printed result, a Promise instance.

async await

Async/Await is a self-executing generate function. Write asynchronous code as “synchronous” using the properties of generate.

An async function returns a Promise object. When the function executes, it returns an await and waits until the triggered asynchronous operation is complete before executing the following statement in the function body. It can be understood as giving up the thread, out of the async function body.

regular

Special characters

  • ^ Matches the start of the input
  • $matches the end of the input
  • * Matches 0 or more times {0,}
  • + match 1 or more {1,}
  • ?
    • 0 or 1 {0,1}
    • Used for prior assertion
    • If followed by any quantifier *, +,? Or {} will change the quantifier toNot greed
      • Using /\d+/ for “123abc” will return “123”,
      • Use / \ d +? /, then only “1” will be matched.
      • Matches any single character other than a newline
  • (x) matches ‘x’ and remembers the matches
  • (? :x) matches ‘x’ but does not remember the match
  • x(? =y) matches ‘x’ only if ‘x’ is followed by ‘y’. This is called forward positive lookup.
  • x(? ! Y) matches ‘x’ only if ‘x’ is not followed by ‘y’, this is called a positive negative lookup.
  • X | y match ‘x’ or ‘y’.
  • {n} repeat n times
  • {n, m} matches at least n times and at most m times
  • [xyz] stands for X or y or z
  • [^xyz] is not x or y or z
  • \ d digital
  • \ D non-numeric
  • \s Whitespace characters including Spaces, tabs, page feeds, and line feeds.
  • \S non-whitespace character
  • \ W Word characters (letters, digits, or underscores) [A-zA-z0-9_]
  • \W Non-single-word character. [^A-Za-z0-9_]
  • \3 represents the third grouping
  • \b word boundary
    • /\bm/ match “moon” with ‘m’;
  • \B Non-word boundary

Regular expression method

  • Exec a RegExp method that performs a lookup match in a string, which returns an array (null if no match is found)
  • Test A RegExp method that performs a search for a match in a string, returning true or false
  • Match A String method that performs a search for a match in a String, returning either an array or null if there is no match.
  • Search A String method that tests a match in a String, returning the index of the matched position, or -1 on failure.
  • Replace A String method that looks for a match in a String and replaces the matched substring with a replacement String.
  • Split a String using a regular expression or a fixed String, and stores the delimited substrings into an array of String methods.

practice

Matches the number at the end

/\d+$/g
Copy the code

Uniform number of Spaces

If there are Spaces in the string but the number of Spaces may be inconsistent, use the re to unify the number of Spaces into one.

let reg = /\s+/g
str.replace(reg, "");
Copy the code

Determines whether a string consists of numbers

str.test(/^\d+$/);
Copy the code

Phone number regular

  • The area code must contain 3-4 digits
  • Use a hyphen (-) after the area code to connect the 7-8 digits of the phone number
  • The extension number is a 3- to 4-digit number. This parameter is optional, but the extension number can be connected with a hyphen (-)
/^\d{3.4}-\d{7.8}(-\d{3.4})? $/Copy the code

Mobile phone number regular expression

Regular verification mobile phone number, ignore the front 0, 130-139, 150-159 support. I’m going to ignore the 0 and say it’s 11 bits.

/ ^0*1(3|5)\d{9} $/Copy the code

Use regular expression implementations to remove whitespace from strings

function trim(str) {
  let reg = /^\s+|\s+$/g
  return str.replace(reg, ' ');
}
Copy the code

Restrict text boxes to numbers, two decimal points, and so on

/^\d*\.\d{0.2} $/Copy the code

Enter only lowercase letters and decimal points, colons, and forward and backward slashes (:./).

/^[a-z\.:\/\\]*$/
Copy the code

Replace the content before the decimal point with the specified content

For example: infomarket. PHP? Id =197 instead of test.php? id=197

var reg = + / / ^ [^ \];
var target = '-- -- -- -- -- -- -- -- --';
str = str.replace(reg, target)
Copy the code

Matches only Chinese regular expressions

/[\u4E00-\u9FA5\uf900-\ufa2d]/ig
Copy the code

Returns the number of Chinese characters in a string

Remove the non-Chinese characters and return the length attribute.

function cLength(str){
  var reg = /[^\u4E00-\u9FA5\uf900-\ufa2d]/g;
  // Matches non-Chinese regular expressions
  var temp = str.replace(reg,' ');
  return temp.length;
}
Copy the code

The regular expression matches the first three segments of the IP address

Just match the last paragraph and replace it with an empty string

function getPreThrstr(str) {
  let reg = / \ \ d {1, 3} $/;
  return str.replace(reg,' ');
}
Copy the code

Matches the content between <ul> and </ul>

/<ul>[\s\S]+?</ul>/i
Copy the code

Get the file name using a regular expression

C :\images\tupian\006.jpg May be directly in the root directory of the disk, or may be in several layers of the directory, requiring only the file name to be replaced. Matches zero or more characters that are not left and right slashes first, and then one or more left and right slashes.

function getFileName(str){
  var reg = /[^\\\/]*[\\\/]+/g;
  // XXX \ or XXX /
  str = str.replace(reg,' ');
  return str;
}
Copy the code

An absolute path is disguised as a pair of paths

“Http://23.123.22.12/image/somepic.gif” to: “/ image/somepic. GIF”

var reg = /http:\/\/[^\/]+/;
str = str.replace(reg,"");
Copy the code

User name re

For user name registration, the user name can contain only Chinese, English, digits, underscores (_), and 4-16 characters.

/^[\u4E00-\u9FA5\uf900-\ufa2d\w]{4.16} $/Copy the code

Match English address

The rules are as follows: contains “dots “,” letters “,” Spaces “,” commas “, and” digits “, but cannot begin or end with any character other than letters.

/^[a-zA-Z][\.a-zA-Z,0-9]*[a-zA-Z]$/
Copy the code

Regular matching price

A number of leading digits, possibly with a decimal point, followed by two digits.

/^\d+(\.\d{2})? $/Copy the code

Matching of id numbers

The ID number can be 15 or 18 digits, with the last digit being an X. Everything else is just numbers

/^(\d{14}|\d{17})(X|x)$/
Copy the code

Capitalize the first letter

Capitalize the first word of each word, lower case the rest. For example, blue Idea is converted to Blue Idea, and blue Idea is also converted to Blue Idea

function firstCharUpper(str) {
  str = str.toLowerCase();
  let reg = /\b(\w)/g;
  return str.replace(reg, m= > m.toUpperCase());
}
Copy the code

The re validates the date format

Yyyy-mm-dd format four digits, line, one or two digits, line, and finally one or two digits.

/^\d{4}-\d{1.2}-\d{1.2} $/Copy the code

Remove file name extensions

www.abc.com/dc/fda.asp 变为 www.abc.com/dc/fda

function removeExp(str) {
  return str.replace(/\.\w$/.' ')}Copy the code

Validates the mailbox’s regular expression

It must start with one or more word characters or -, plus at sign, and then one or more word characters or -. And then click “.” And the word character and -, can have one or more combinations.

/^[\w-]+@\w+\.\w+$/
Copy the code

The re determines whether the label is closed

For example: <img XXX = “XXX” is no closed tag;

The contents of p are also open labels.

Tags can be closed in two ways,Or is it

xxx

/<([a-z]+)(\s*\w*? \s*=\s*". +?")*(\s*? >[\s\S]*? (< 1 > \ / \)+|\s*\/>)/i
Copy the code

The re determines whether it is a combination of numbers and letters

It must contain a combination of letters and digits and cannot be smaller than 12 characters

/^(([a-z]+[0-9] +) | ([0-9]+[a-z]+))[a-z0-9]*$/i
Copy the code

Replace Arabic numerals with Chinese uppercase forms

function replaceReg(reg,str){
  let arr=["Zero"."One"."贰"."叁"."Boss"."Wu"."Lu"."Pure".""."Nine"];
  let reg = /\d/g;
  return str.replace(reg,function(m){return arr[m];})
}
Copy the code

Remove all attributes of the tag

<td style="width: 23px; height: 26px align="left">* * *</td>It becomes without any properties<td>* * *</td>
Copy the code

Instead of capturing a matching attribute, capture a matching tag and replace the string with the result. The re is as follows:

/ (
      
       )
      )\s(?>Copy the code

The garbage collection

JavaScript garbage collection

Mark and sweep

  • This is aJavaScriptThe most common way to collect garbage is when a variable enters the execution environment, such as declaring a variable in a function, the garbage collector marks it as “in the environment” and marks it as “out of the environment” when the variable leaves the environment (the function ends).
  • The garbage collector marks all variables stored in memory at runtime and then removes variables in the environment and variables referenced by variables in the environment (closures). Variables that remain marked after completion are the ones to be deleted.

Reference Counting (Reference Counting)

  • In the low versionIEMemory leaks are common in garbage collection, often due to reference counting. Reference counting strategy is to track the number of each value is used, when declaring a variable and will be assigned to a reference type change in the value of citations add 1, if the value of the variable into another, then the value of reference number minus 1, when the value of citations to 0, show that no variable in the references, This value can no longer be accessed, so it can be reclaimed, so that the garbage collector will clean up the space occupied by the zero reference value at run time

See Link Memory Management -MDN

Garbage collection mechanism under V8

V8 implements accurate GC and GC algorithm adopts generational garbage collection mechanism. V8 therefore divides memory (heap) into the new generation and the old generation

  • New generation algorithm

    • Cenozoic objects generally live for a short time, useScavenge GCAlgorithm.
      • In the new generation space, the memory space is divided into two parts, respectivelyFromSpace andToSpace. Of these two Spaces, one must be used and the other free. The newly allocated object is put inFromIn space, whenFromWhen space is covered, the new generationGCIt’s going to start. The algorithm will detectFromObjects that live in space and copy toToIn space, objects that are deactivated are destroyed. When the copy is completeFromSpace andToSpace interchange, like thisGCWill be over
  • Old generation algorithm

    • Objects in the old generation generally live for a long time and have a large number. Two algorithms are used, respectivelyMark-sweep algorithmandMark Compression Algorithm (Mark-Compact). Objects appear in old space as follows
      • Whether objects in the new generation have already experienced oneScavengeAlgorithms, if experienced, move objects from the Cenozoic to the old.
      • ToThe object proportion size of the space exceeds25%. In this case, objects are moved from the new generation space to the old generation space in order not to affect memory allocation.
    • Mark-sweep
      • Mark-sweep iterates over all objects in the heap during the marking phase and marks living objects, and only unmarked objects are cleared during the subsequent cleaning phase. The biggest problem with Mark-Sweep was the discontinuous state of memory space after a Mark Sweep collection. In order to solve this memory fragmentation problem, Mark-Compact was proposed.
    • In mark-Compact, living objects are moved to one end of the Compact. When the move is complete, the memory outside the boundary is cleared.

A memory leak

The requested memory is not reclaimed in a timely manner, causing memory leaks

Why does a memory leak occur?

Although there is garbage collection on the front end, a memory leak occurs when a piece of unused memory cannot be considered garbage by the garbage collection mechanism

Garbage collection mechanisms typically use a flag cleanup strategy, which simply refers to whether the node is reachable from the root node to determine whether it is garbage

The above is the root cause of a memory leak. The direct cause is that when two things with different life cycles communicate with each other, a memory leak occurs when one of them is held by the other when its life is due for recycling

What can cause a memory leak

  • Unexpected global variables
  • Timer for forgetting
  • Improper use of closures
  • Missing DOM elements
  • Network callback

How do I monitor memory leaks

Memory leaks can be divided into two types: one is more serious, and the leaked memory can never be recovered; the other is less serious, that is, the memory leaks caused by the timely cleaning can still be cleaned up after a period of time

In either case, a memory graph captured using the developer tools should see a continuous linear decrease in memory usage over a period of time due to GC, or garbage collection

For the first, more serious type, you will find that the total amount of memory used in the memory graph continues to grow even after GC is continuously occurring

In addition, running out of memory can cause continuous GC, which blocks the main thread, affecting page performance and causing lag, so memory leaks are still a concern

For example scenario

Allocate a block of memory within a function that is then called repeatedly for a short period of time

// Click the button, execute the function once, request a block of memory
startBtn.addEventListener("click".function() {
	var a = newArray(100000).fill(1);
	var b = newArray(20000).fill(1);
});
Copy the code

There is a limit to how much memory a page can use, and when it runs out, garbage collection is triggered to reclaim unused memory

The variables used inside the function are local variables, and when the function is finished, the memory block is useless and can be reclaimed

Therefore, when we call this function repeatedly for a short period of time, we can find that the function is running out of memory, and the garbage collection mechanism works to reclaim the memory requested by the previous function, because the last function has been executed, and the memory can be reclaimed

How do I analyze memory leaks to find problematic code

Take advantage of developer tools’ Memory capabilities

The last

Article so far, thank you for reading, one key three even is the biggest support for me.