1. Why is JS single threaded

A simple reason is that JS is designed at the beginning of some simple form verification, which does not need multithreading, single thread can do the job. Even after the rapid development of the front-end, carrying more and more capacity, did not develop to the extent of multi-threading.

And there is a main reason, imagine, if JS is multithreaded, multiple threads operate on DOM elements at the same time, that specific which thread is the main problem, thread scheduling problem is a more complex problem.

The new HTML5 standard allows the use of new Worker to start a new thread to run a separate JS file script, but the new thread has strict requirements on the functions that can be used. For example, it can only use ECMAScript and cannot access DOM and BOM. This limits the possibility of multiple threads manipulating DOM elements at the same time.

2. Write a triangle script using the CSS

The width and height of the element is set to 0, and the border property is set to make the other three directions transparent or consistent with the background color, and the remaining border color is set to the desired color.

div {
    width: 0;
    height: 0;
    border: 5px solid #transparent;
    border-top-color: red;
}
Copy the code

3. Center horizontally and vertically

I usually only use two ways to locate or Flex, and I think that’s enough.

div {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
}
Copy the code

The parent control subset is centered

.parent {
    display: flex;
    justify-content: center;
    align-items: center;
}
Copy the code

4. One line of CSS text exceeds…

overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
Copy the code

5. Multiple lines of text beyond display…

display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
Copy the code

6. The container scroll bar on IOS phones does not slide smoothly

overflow: auto;
-webkit-overflow-scrolling: touch;
Copy the code

7. Modify the scroll bar style

Hide the scroll bar for the div element

div::-webkit-scrollbar { display: none; The \}Copy the code

Div ::- webKit-ScrollBar The overall part of the scrollbar

Div ::-webkit-scrollbar-thumb Small square inside the scrollbar that can be moved up and down (or left and right, depending on whether it’s vertical or horizontal)

Div ::-webkit-scrollbar-track Specifies the track of the scrollbar

Div ::- webkit-Scrollbar-button Buttons at both ends of the scrollbar track that allow fine tuning of the position of small squares by clicking.

Div ::-webkit-scrollbar-track-piece inner track, middle part of scrollbar

Div ::- webkit-Scrollbar-corner corner, i.e. the intersection of two scroll bars

Div ::-webkit-resizer Small control at the intersection of two scroll bars used to resize elements by dragging

Note that this scheme has compatibility problems. Generally, when I need to hide the scrollbar, I use a color block to cover it by positioning, or I make the child element larger, and the parent element uses overflow-hidden to cut off the scrollbar. Violent and direct.

8. Solve the problem that ios Audio cannot automatically play and loop playback

If audio or video playback on aN ios phone cannot be automatically played, you can use the following code hack.

Var music = document.getelementbyid ('video'); var music = document.getelementbyid ('video'); var state = 0; document.addEventListener('touchstart', function(){ if(state==0){ music.play(); state=1; } }, false); document.addEventListener("WeixinJSBridgeReady", function () { music.play(); }, false); Music.onended = function () {music.load(); music.play(); }Copy the code

9. Hide page elements

Display-none: Elements take up no space, are not displayed on the page, and child elements are not displayed.

Animation-0: The transparency of the element will be zero, but the element will still exist and the bound events will still be valid and trigger execution.

Visibility -hidden: The element is hidden, but it still exists, occupies space, and cannot be triggered in the page.

10. Front-end engineering

A lot of people think of WebPack when they think of front-end engineering, but that’s not true. Webpack is just one part of front-end engineering. In the whole engineering process, he helped us solve most problems, but not all problems.

Front-end engineering is a tool to improve efficiency and reduce costs.

In recent years, it has been widely concerned and discussed. The main reason is that the functional requirements of modern front-end applications are constantly improving and business logic is increasingly complex. As the only indispensable technology in the Internet era, front-end can be said to occupy half of the entire development industry. From traditional websites to H5 now, mobile apps, desktop applications, and small programs. The front end is almost omnipotent in terms of comprehensive coverage.

Behind the facade, is actually the industry requirement for developers changed, ever front write demo, set of templates, the page this way of slash-and-burn has completely do not conform to the requirements of the present on the efficiency of the development, the front-end engineering is under such a background is on the table, become one of the means of front-end engineers must.

Generally speaking, front-end engineering includes, project initialization, project development, submission, construction, deployment, testing, monitoring and other processes. Engineering is to solve these problems from the point of view of engineering. For example, we usually use NPM init for project initialization, plop for page template creation, we like to use ES6+ development, but need to code ES5 via Babel, we use Git/CI CD for continuous integration, but we introduced ESLint to keep the development specification, Deployment usually uses Git/CD, Jenkins, etc.

11.contenteditable

Most tags in HTML are not editable, but with the addition of the contenteditable property, they become editable.

<div contenteditable="true"></div>
Copy the code

However, when you put the tag into editable state with this attribute, there is only an input event, not a change event. You can’t control the maximum length by maxLength as you can on a form. I also forget the circumstances in which I used it, so I’ll fix it later.

12.calc

This is a CSS property, which I usually call a CSS expression. You can calculate the CSS value. The most interesting thing was that he could calculate the difference between different units. A very useful feature, the disadvantage is that it is not easy to read. I can’t see 20px at a glance.

div {
    width: calc(25% - 20px);
}
Copy the code

13. The Date object

Gets the current time millisecond value

// Date.now(); // 1606381881650 // New Date() -0; // 1606381881650 // New Date().getTime() // 1606381881650Copy the code

Creating Date objects is incompatible.

// New Date('2020-11-26') is not supported on ios and MAC; // New Date('2020/11/26') is supported on ios and MAC;Copy the code

14. The difference between Proxy and Object.defineProperty

Proxy means a Proxy, and I usually call it an interceptor, that intercepts an operation on an object. The usage is as follows: create an object by new, the first parameter is the object to be intercepted, and the second parameter is the description of the object operation. Instantiation returns a new object, and when we operate on this new object we call the corresponding method in our description.

new Proxy(target, {
    get(target, property) {

    },
    set(target, property) {

    },
    deleteProperty(target, property) {

    }
})
Copy the code

Proxy differs from Object.definedProperty.

Object.defineproperty can only listen to read and write of attributes, while Proxy can also listen to delete attributes and call methods in addition to read and write.

In general, if you want to monitor array changes, you basically override array methods, which is how Vue does it, and Proxy can monitor array changes directly.

const list = [1, 2, 3]; const listproxy = new Proxy(list, { set(target, property, value) { target[property] = value; return true; }}); list.push(4);Copy the code

Proxy regulates the read and write of objects in a non-intrusive manner, while defineProperty needs to define the attributes of objects in a specific way.

15.Reflect

Static objects, which cannot be drawn by instances, can only be called as static methods, similar to Math objects, which can only be called as math.random ().

Reflect internally encapsulates a series of low-level operations on objects, 14 of which are deprecated, leaving 13.

Reflect’s static methods are exactly the same as those in the Proxy description. That is, the Reflect member method is the default implementation of Proxy handling objects.

The default Proxy method calls Reflect’s internal processing logic, which means that if we call get, internally Reflect hands get back to Reflect as shown below.

const proxy = new Proxy(obj, { get(target, property) { return Reflect.get(target, property); }})Copy the code

Reflect and Proxy do not have an absolute relationship, and we use them together to make it easier to understand them.

So why Reflect? Its main use is to provide an API for manipulating objects.

To determine whether an object has an attribute, you can use the in operator, but it’s not elegant. You can also use reflect. has(obj, name); To delete a property, use either delete or reflect.deleteProperty (obj, name); Get all attribute names either object. keys or reflect.ownkeys (obj); We prefer to use Reflect’s API to manipulate objects because it’s the future.

16. Parse the GET parameter

The replace method is used to get the parameter key-value pairs in the URL and quickly parse the GET parameters.

const q = {};
location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);
console.log(q);
Copy the code

17. Parse the connection URL

You can obtain the protocol, PathName, Origin and other attributes on location objects by creating a tag and assigning href attribute to a tag.

Const aEle = document.createElement('a'); Href path aEle. Href = '/test.html'; // Access the attribute aEle. Protocol; // Get protocol aEle. Pathname; // Get path ael.origin; aEle.host; aEle.search; .Copy the code

18.localStorage

LocalStorage is the permanent storage space provided by H5. Generally, it can store up to 5M data and supports cross-domain isolation. Its emergence greatly improves the possibility of front-end development. The use of localStorage is well known as setItem, getItem,removeItem, but it can also operate directly as a member.

localStorage.name = 'yd'; / / get localStorage. Name; // yd // delete delete localstorage. name; // Clear all localstorage.clear (); For (let I = 0; i < localStorage.length; i++) { const key = localStorage.key(i); // obtain the localStorage Key localStorage[Key]; // Get local storage value}Copy the code

Continuing to store when localStorage is full does not overwrite other values. Instead, an error is reported (QuotaExceededError) and the current stored value is emptied. The browser supports 5M data for each domain name.

19.sessionStorage

The difference between sessionStorage and localStorage is that there is A current session, many people understand that the browser is closed, this is not correct, suppose you store sessionStorage in page A, new TAB to paste the link of page A to open the page, SessionStorage also does not exist.

Therefore, the condition for the existence of sessionStorage is the jump between pages. Page A stores sessionStorage, and it can access sessionStorage only by opening another same-domain page through hyperlink, location.href or window.open.

This is especially important in hybrid H5 nested development mode, if you open the page as a new WebView, it is likely that the sessionStorage will not exist.

20. A session cookie

If the expiration time is not set when cookie is set, it means that it is a session cookie. Before, I thought that closing the browser session cookie disappeared, but… Here’s a bug.

This is true for Windows or Android in most cases. However, in macOS or ios, closing the browser does not clear session cookies, but ends the browser process.

21. Label template string

Template strings can be preceded by a function whose first argument is an array of fixed contents, followed by the variables passed in, and which returns the value that the template string actually represents. But this function personally feels useless.

const tag = (params, ... args) => { return params[0] + args[0]; // Return the true value of the template string. } const str = tag`hello ${'world'}`;Copy the code

22. Common methods for strings

1. includes();

If a string contains a string, it’s a more elegant alternative to indexOf,

2. startsWith();

If a string starts with a string, I usually use that to determine if the URL has HTTP

3. endsWith();

Whether the string ends in a string. This is especially true when judging suffixes.

4. repeat(number);

Get a string that repeats the number multiple times. Er… I don’t know when it’s useful, but I use it to build test data.

5. ‘abc’.padEnd(5, ‘1’); // abc11;

Concatenate the end of the given string to the specified length, with the first argument being the length and the second argument being the value used for concatenation.

6. ‘abc’.padStart(5, ‘1’); // 11abc;

Concatenate the header to the specified length with the given string. The first argument is the length, and the second argument is the value used for concatenation. Plus zero at the head?

23. Quick array de-duplication

Most of you probably know this, you convert an array to a Set and then to an array, but this way you can only get rid of arrays of primitive data types.

const arr = [1, 2, 3, 4, 5, 6];

const arr2 = new Set(arr);

const arr3 = [...arr2];
Copy the code

24.Object.keys, values, entries

Keys, which returns an array of the keys of an Object, and values, which returns an array of Object values. Object.entries convert objects into arrays, where each element is an array of key-value pairs.

const obj = {name: 'yd', age: 18};

Object.keys(obj); // ['name', 'age'];

Object.values(obj); // ['yd', 18];

const l = Object.entries(obj); // [['name', 'yd'], ['age': 18]];

const m = new Map(l);
Copy the code

25.Object.getOwnPropertyDescriptors

Gets the description of an object

Object.assign copies the attributes and methods of the Object as common attributes, but does not copy complete description information, such as this.

const p1 = { a: 'y', b: 'd', get name() { return `${this.a} ${this.b}`; } } const p2 = Object.assign({}, p1); p2.a = 'z'; p2.name; // y d; P2.a is not changed because this still refers to p1Copy the code

Use Object. GetOwnPropertyDescriptors for complete description information

const description = Object.getOwnPropertyDescriptors(p1);

const p2 = Object.defineProperty({}, description);

p2.a = 'z';

p2.name; // z d
Copy the code

26.BigInt

The largest Number that JavaScript can handle is 2 to the power of 53 -1, which we can see in number.max_safe_INTEGER.

consoel.log(Number.MAX_SAFE_INTEGER); / / 9007199254740991Copy the code

Larger numbers cannot be processed, and ECMAScript2020 introduces the BigInt data type to solve this problem. You can manipulate big data by putting the letter N at the end.

BigInt can add, subtract, multiply, divide, remainder, and idempotent operations using arithmetic operators. It can be constructed from numbers and hexadecimal or binary strings. It also supports bitwise operations such as AND, OR, NOT, AND XOR. The only invalid bit operation is the zero-fill right-shift operator.

const bigNum = 100000000000000000000000000000n;
console.log(bigNum * 2n); // 200000000000000000000000000000n

const bigInt = BigInt(1);
console.log(bigInt); // 1n;

const bigInt2 = BigInt('2222222222222222222');
console.log(bigInt2); // 2222222222222222222n;
Copy the code

BigInt is a large integer, so it cannot be used to store decimals.

27.?? Merge air transport operator

Assume that variable a does not exist, we hope to give the system a default value, normally we would use | | operators. But in the hollow javascript string 0, false will perform | | operators, so ECMAScript2020 combined air operator is applied to deal with the problem, only allowed when the value is null or undefined using default values.

const name = '';

console.log(name || 'yd'); // yd;
console.log(name ?? 'yd'); // '';
Copy the code

28.? Optional chain operator

It’s very common in business code that an object a has an attribute B, and an object B has an attribute C,

We need to access c, often written as A.B.C, but if f does not exist, an error will occur.

const a = { b: { c: 123, } } console.log(a.b.c); / / 123; console.log(a.f.c); // f does not exist so an error is reportedCopy the code

ECMAScript2020 defines optional chain operators to solve this problem by using the Before I add one? Make the key name optional

let person = {}; console.log(person? .profile? .age ?? 18); / / 18Copy the code

29.import

Import is a set of ES Module modules defined in ECMAScript2015. The syntax features are already supported by most browsers. You can use ES Module standards to execute javascript code by adding type= Module attributes to script tags.

<script type="module">
console.log('this is es module');
</script>
Copy the code

Under the ES Module specification, javascript code is run in use strict mode. Each ES Module runs in a separate scope, which means variables don’t interfere with each other. External JS files are requested in the way of CORS, so we are required to support the external JS file address to support cross-domain request, that is, the file server to support CORS. We can enter the following code at any website console.

const script = document.createElement('script'); script.type = 'module'; script.innerHTML = `import React from 'https://cdn.bootcdn.net/ajax/libs/react/17.0.1/cjs/react-jsx-dev-runtime.development.js'; `; document.body.append(script);Copy the code

Request the https://cdn.bootcdn.net/ajax/libs/react/17.0.1/cjs/react-jsx-dev-runtime.development.js resources can be found on the network.

The ES Module script tag delays script loading until the web page has requested the resource, just like deffer loading the resource.

Note that when import {} from ‘xx’ is imported into a module, it is not the deconstruction of the object, but the fixed syntax of import, which is often mistaken.

In ECMAScript2020, import supports dynamic import. Before that, import could only be written at the top of the module code, and other modules that the module depended on were declared at the beginning. With the support of dynamic import, corresponding modules can be introduced as needed, which has been used in SPA. A dynamic import returns a Promise.

a.js

const a = 123;
export { a };
Copy the code

b.js

import('./a.js').then(data => { console.log(data.a); / / 123; })Copy the code

30. 0.1 + 0.2 === 0.3 // false

The console. The log (0.1 + 0.2); / / 0.30000000000000004Copy the code

In JS, the Number type is actually a double, and there is an accuracy problem with decimals. Since the computer only understands binary, it needs to convert the values of other bases into binary before performing the calculation

Decimals are infinite when expressed in binary.

// Convert 0.1 to binary console.log(0.1.tostring (2)); / / / / will be converted to binary console. 0.2 0.0001100110011001100110011001100110011001100110011001101 log (0.2 toString (2)); / / 0.001100110011001100110011001100110011001100110011001101Copy the code

The decimal part of a double-precision floating point number supports a maximum of 53 binary bits. Therefore, when the two digits are added together, the binary number truncated due to the limitation of the decimal bits of the floating point number is converted to decimal, resulting in 0.30000000000000004. This will cause an error in arithmetic calculation.

ES6 adds a tiny constant Number.EPSILON to the Number object. According to the specification, it represents the difference between 1 and the smallest floating point number greater than 1. For 64-bit floating-point numbers, the minimum floating-point number greater than 1 is equivalent to binary 1.00.. 001, 51 consecutive zeros after the decimal point. So when you subtract 1 from this, you get 2 to the minus 52.

Number.EPSILON === Math.pow(2, // true number.epsilon // 2.220446049250313E-16 number.epsilon. toFixed(20) // "0.00000000000000022204"Copy the code

Number.epsilon is actually the minimum precision that JavaScript can represent. If the error is less than that, it is considered meaningless, that is, there is no error.

The purpose of introducing such a small quantity is to set a margin of error for floating-point calculations. We know that floating-point meters are imprecise.

Number.EPSILON can be used to set an acceptable error range. For example, the margin of error is set to 2 to the -50 power (that is, number.epsilon * math.pow (2, 2)), which means that if the difference between two floating points is less than this value, we consider them equal.

Thank you