You are in Pinduoduo looking for people to haggle prices, he is in Didi Dache asking for help, I am in the electronics factory to screw until early morning, we all have a bright future! Good morning, worker!

wedge

As a front end worker with iron will, it is impossible to install force, this life is impossible to install force. If you’re going to pretend to be puss, then we should pretend to be puss together. After all, we have to talk about martial art in front of us. We need rat tail juice. Then decided to write down the front end of the installation force skills 108, for you after dinner a happy, even from time to time show a SAO operation, to work for the life to add a bright color.

Because as a worker, time and energy is limited, the current outline is only about 50 types, but also hope you have a good knowledge point of private message or in the comment area, everyone together to install force, to meet the bright future of workers!

Limited by the style of the article, the cited sources will be indicated at the end of the corresponding section.

The Master said, if the public wants to install the force well, tools are indispensable

  • Carbon comes to the rescue: Turn your code into a beautiful image to share (click on the image to jump)

In order to facilitate code replication, this article will adhere to the principle of no first install force, as far as possible to reduce the use of this install force tool.

The second type:consoleDebug the panacea, learn to drive higher

The status of console.log() in the front-end debugging is needless to mention, in fact, a generation of car god is also deeply impressed by it, you do not believe that you stick the following code to the console for a close look (dig gold do not let the sticker 😶🌫️, if you really have puzzled about it, it is recommended to carry forward the spirit of seeking knowledge, ask your colleague 😂) :

// In order to avoid generating ugly serrate background images, please pay attention to the number of Spaces and ensure the width of the console panel.
console.log(
  `%c %c FBI WARNING %c %c Federal Law provides severe civil and criminal penalties for the unauthorized reproduction,distribution, or exhibition of copyrighted motion pictures (Title 17, United States Code, Sections 501 and 508). The Federal Bureau of Investigation investigates allegations of criminal copyright infringement (Title 17, United States Code, Section 506). `.'background: #000; font-size: 18px; font-family: monospace'.'background: #f33; font-size: 18px; font-family: monospace; color: #eee; text-shadow:0 0 1px #fff'.'background: #000; font-size: 18px; font-family: monospace'.'background: #000; font-size: 18px; font-family: monospace; color: #ddd; text-shadow:0 0 2px #fff'
);
Copy the code

Why is that? You probably remember print() from other languages. Are placeholders exclusive to print()? No, they apply to console.log() as well:

  • %sString:
  • %d: an integer
  • %i: an integer
  • %f: a floating point number
  • %o: obj object (DOM)
  • %OObject: obj
  • %c: CSS style

Console.log () can process the output of information through these unique placeholders. Yes, you may already know that the magic of the above code is the four % cs, the first of which creates a mysterious and sexy pure black background; The second adds “FBI WARNING” with a red background; The third restores the sexiness of pure black; The fourth with white text, so, the event is done.

Understand the above principles, you can freely play, show your powerful CSS strength, and even output GIF background, in the way of loading force on a few more floors. No, I’m a CSS scum.

console.log(
  '% c solitary sail'.'text-shadow: 0 1px 0 # CCC,0 2px 0 #c9c9c9,0 3px 0 # BBB,0 4px 0 #b9b9b9,0 5px 0 #aaa,0 6px 1px rgba(0,0,0, 1),0 0 5px rgba(0,0,0, 1),0 1px 3px rgba(0,0,0,.3),0 3px 5px Rgba (0,0,0,.2),0 5px 10px Rgba (0,0,0,.25),0 10px 10px Rgba (0,0,0,.2),0 20px 20px Rgba (0, 0, 15); font-size:5em'
);
Copy the code

So, whether we can surpass Baidu, in the official website console to complete the exquisite recruitment copy delivery?

Extension: What are the methods of the console object?

Resources: a small tadpoles diary: through the console log high copy the FBI Warning | Using the F12 Tools the console to View Errors and Status | console. The log can also be illustrated!!!!!!

Third type: lotus face, willow waist, nothing more enchanting – let you see the outline of UI

  • Where to find UI Outlines, the Outline property helps you.

    html * {
      outline: 1px solid red;
    }
    Copy the code

  • Analysis and thinking

    • The reason we don’t use border here is that border increases the size of the element but outline does not;
    • This technique not only helps us quickly understand where elements are in development, but also helps us easily see the layout of any site;
    • All browsers support the Outline attribute; An outline is a line drawn around an element, just outside the border edge, to highlight the element;
    • The contours do not take up space and are not necessarily rectangular (e.g., 2D conversions, etc.).
    • Remove the colored border that gives focus to input boxes and other form controls in Chrome
      input {
        outline: none;
      }
      Copy the code
  • Any web page can be turned on or off with a switch

    • “New bookmarks” is added to Chrome.
    • Paste the following code into the url.
    • Then we can click on the bookmark we just created on any website, and it will internally determine whether the debug style exists. Delete it if it exists, add it if it doesn’t, and this way we can easily view the layout of any web page with this trick.
    javascript: (function () {
      var elements = document.body.getElementsByTagName(The '*');
      var items = [];
      for (var i = 0; i < elements.length; i++) {
        if (
          elements[i].innerHTML.indexOf('html * { outline: 1px solid red }') != -1) { items.push(elements[i]); }}if (items.length > 0) {
        for (var i = 0; i < items.length; i++) {
          items[i].innerHTML = ' '; }}else {
        document.body.innerHTML +=
          '<style>html * { outline: 1px solid red }</style>';
      }
    })();
    Copy the code

Resources: Great UI debugging tips

Type 4: horn sound cold, night, and change demand. Hard, hard, hard! — Type conversions help you curse your products and praise yourself gracefully

  • (! (~ + []) + {}) [- [~ + ""] + [[]] * [~ + []] + ~ ~! + []] + + [] ({}) [[~! ~ + + [] * []]]: sb
  • ([[]] + [] []) [+!! []] + [[] + {}) [! + [] +!! []]: nb
  • (+!!!!! * ([] + [] {}) + [], [[]] + + {}) ([] + {}) [! + [] +!! []]: Nb

Diagram: Take the characters of the cast string and put them together.

Zhuangbility, an NPM plug-in that can operate backwards, enter text, and return operators

The fifth type:a == 1 && a == 2 && a == 3“Then you can do ita === 1 && a === 2 && a === 3?

  • A == 1 && a == 2 && a == 3:

    // Of course, you can also put count as a property on the a object
    let count = 1;
    let a = {
      valueOf: function () {
        returncount++; }};console.log(a == 1 && a == 2 && a == 3); // true
    Copy the code
    • Object is called when the base type is convertedvalueOftoStringThe return value of this method is the result of a conversion to a primitive type
    • What exactly is called depends on the built-intoPrimitiveThe results
  • A === 1 && a === 2 && a === 3:

let count = 1;
Object.defineProperty(window.'a', {
  get: function () {
    returncount++; }});console.log(a === 1 && a === 2 && a === 3); // true
Copy the code

The object.defineProperty () method directly defines a new property on an Object, or modifies an existing property on an Object, and returns the Object. This API is also at the heart of Vue 2.x’s data binding implementation, which Vue implemented with a Proxy after version 3.x, and which will be discussed briefly later in this series.

Principle can be reference: [translate] in JS, how to make (a = = = 1 & 2 & & a = a = = = = = 3) (strict) equal value is true? | | a simple Object. DefineProperty () ECMAScript7 ToPrimitive abstract operations in the specification

Type 6: The Web Components that are getting a little hot these days may not be fresh meat

  • HTML is very loose, and browsers can recognize irregular, illegal tags (elements) (e.g<custom-label>Web Components</custom-label>“Web Components” is displayed.) ;
  • Custom is inherited fromHTMLElementClass, called the custom element class;
  • afterwindow.customElements.defineThe API defines and registers custom elements to enableIllegal label(custom element) is associated with the class of the custom elementThe legalization of;
  • By template tag<template>Simplify class definition and add styles;
  • By customizing the elementattachShadow()Method to enable Shadow DOM (this part of the DOM is isolated from the external DOM by default, and no code inside the DOM can affect the external DOM) to hide the internal implementation of custom elements.
  • Add event listener, perform componentization encapsulation, etc.

Resources: introduction to Web Components instance tutorial – nguyen Window. The other | customElements | Web Components

Type 7: Setting Windows environment variables can be simple

Setting environment variables can also be as simple as this:

Select * from 'set' where 'path' is' set 'where' path 'is' set' where 'path' is' set 'where' path 'is' Set variable name = # append variable (% variable name %; Set name =% variable name %; C:\Go\bin\ add C:\Go\bin\ to path set path=%path%; C:\Go\bin\ ```Copy the code

Resources: Windows uses the CMD command line to view, modify, delete, and add environment variables

The first BaShi:1.toFixed(),1.0. ToFixed ()and1.. toFixed()Which one is right?

In numeric literals, syntax such as 1.xxxxx is floating point representation. So 1. ToFixed () is an error in JavaScript that comes from the literal parsing of floating-point numbers, not from “. As an access operator. In JavaScript, small bits of floating point numbers can be empty, so “1.” and “1.0” are resolved as the same floating point number. So there will be:

1= = =1; // true
1= = =1.0; // true
1= = =1.0; // true
1; / / 1
1.0; / / 1
Copy the code

Since “1.” represents a floating point number, “1.. ToFixed “represents the”.tofixed “property of the floating point number surface. When it is a numeric literal, you can create a basic wrapper type (display boxing) by something like Number(1).tofixed (), and then properties and methods can be added and read (or you can enclose the literal in parentheses to tell the browser engine that it is a whole).

  • Packing: the operation of converting a basic data type to the corresponding reference type (packing is divided into implicit packing and explicit packing);
  • Unboxing: Converts a reference type to a basic data type.

Basic types cannot have properties or methods. When you add properties to them, the system wraps the class and destroys it automatically:

var num = 1;
num.len = 2;
// The previous line of code produces the following procedure:
// new Number(1).len =2;
// delete len;
// The next line will print num as 1 without len.
console.log(num, num.len); //1 undefined
var num = new Number(1);
num.len = 2;
console.log(num); // Number {1, len: 2}
Copy the code

Talk about packing and unpacking in JavaScript

How can we judge typeof?

  • Typeof of: As we all know, typeof can be used to accurately determine basic types other than null, as well as function and symbol types. Null is considered object by Typeof.

    • In the original implementation of JavaScript, values in JavaScript were represented by a tag representing the type and the actual data value. The type tag of the object is 0. Since null represents a null pointer (0x00 on most platforms), the type tag of null is 0, and typeof NULL therefore returns “object”;
    • Before ES 6, Typeof was always guaranteed to return a string for any given operand. Typeof can return ‘undefined’ even for undeclared identifiers. You never throw an error with Typeof. However, after adding a block-scoped let and const, using Typeof on a let or const in a block before it is declared raises a ReferenceError. A block-scoped variable is in a “temporary dead zone” at the head of the block until it is initialized, during which time an error will be raised.
  • In the past, we used to use an instanceof B to determine whether a is an instanceof B, that is, whether a has a B constructor on the prototype chain (array.isarray () can be used to determine whether an Array is an Array after ES6).

    // L represents the left expression and R represents the right expression
    const customInstanceof = (L, R) = > {
      if (typeofL ! = ='object') return false;
      while (true) {
        // We have traversed to the top
        if (L === null) return false;
        // Use the prototype chain to judge
        if (R.prototype === L.__proto__) return true; L = L.__proto__; }}; customInstanceof([],Array); // true
    Copy the code
  • Why wasn’t Constructor our choice?

    • The constructor attribute can be modified, resulting in incorrect results detected;
    • In addition toundefinedandnull, other types of variables can be usedconstructorIdentify the type.
      let bool = true;
      bool.constructor == Boolean; //true
      let num1 = 1;
      num1.constructor == Number; //true
      let num2 = new Number(a); num2.constructor ==Number; //true
      // The constructor attribute can be modified
      num2.constructor = Object;
      num2.constructor == Number; //false
      let str = 'hello world';
      str.constructor == String; //true
      Copy the code
  • Object. The prototype. ToString so universal?

    Object.prototype.toString.call(123);
    //"[object Number]"
    Object.prototype.toString.call('str');
    //"[object String]"
    Object.prototype.toString.call(true);
    //"[object Boolean]"
    Object.prototype.toString.call({});
    //"[object Object]"
    Object.prototype.toString.call([]);
    //"[object Array]"
    // Define the getType method to determine the type
    getType = (obj) = > {
      return Object.prototype.toString.call(obj).slice(8, -1);
    };
    getType(12n); // BigInt
    getType(Symbol()); // Symbol
    getType(() = > {}); // Function
    getType(); // Undefined
    getType(null); // Null
    getType(NaN); // Number
    Copy the code

Reference data: typeof | The history of “typeof null”

Formula 10: Decimal and binary interconversion, really don’t bother

  • useNumberObject.toString(radix)Decimal to binary:
    // If you want to complete the number of bits, you can add 0 to the front by judging the length of the return value
    let num = 10;
    console.log(num.toString(2)); / / 1010
    Copy the code
  • useparseInt(string, radix);Binary to decimal:
    let num = 1010101;
    console.log(parseInt(num, 2)); / / 85
    Copy the code
  • Tips: Since the above code defines the num variable with a let, how do you execute each of them in the console, other than refreshing the page? Simply place the code between a pair of curly braces (block-level scope).

How to compare the size of positive integer strings without addition, subtraction, multiplication and division?

In some projects I took over, there was a situation that needed to concatenate Elasticsearch query statements at the front end. After some difficulty, I found that the problem was not so simple: you told me to store the string for the amount and quantity interval query? Wouldn’t 1 be less than 3000 and less than 5? Oh, my God. Will you stop teasing me?

So, how do you compare the size of positive integer strings using regular queries without changing ES? If you have more digits or start from the top, a larger number means a larger number.

// Use a regular expression to filter string data greater than a certain value from an array of strings
const filterStrNumberByRegExp = (num, arr) = > {
  const strBaseNumber = num.toString();
  const arrBaseNumber = strBaseNumber.split(' ');
  const len = strBaseNumber.length;
  // Generate re: more digits or higher values starting from higher than,
  let strRegExp = `\\d{${len + 1}} `;
  arrBaseNumber.map((item, index) = > {
    '^' and '$' are not required because of the digit limit
    strRegExp += ` |${strBaseNumber.substring(index, -1) | |A '^'}[${
      +item + 1
    }-9]\\d{${len - index - 1}} $`;
  });
  \d ([0-9]), start match, end match, etc.; the above four lines can be replaced by the following comments
  //let strRegExp = `[0-9]{${len+1}}`;
  //arrBaseNumber.map((item, index) => {
  // strRegExp += `|${strBaseNumber.substring(index,-1) || ''}[${+item + 1}-9][0-9]{${len - index - 1}}`
  / /});
  const regExp = new RegExp(strRegExp);
  // Throw the result of strRegExp to ES for regular query
  console.log(regExp, strRegExp);
  return arr.filter((item) = > {
    // If less than or equal to, change the re
    if (regExp.test(item)) return true;
  });
};
filterStrNumberByRegExp(386['12'.'334'.'556'.'1122'.'5546'.'234'.'388'.'387'.'1234'.'386'.'385',]);// ["556", "1122", "5546", "388", "387", "1234"] ["556", "1122", "5546", "388", "387", "1234"]
Copy the code

Detailed Elasticsearch list page search public method implementation can be viewed in my note.

Type 12: How do you make pages talk to you? — TTS (Text To Speech)

In the project, the message returned by ajax request needs to be broadcasted by voice, and STR is the message to be broadcasted (suitable for error message voice prompt and other scenarios) :

// Voice broadcast
function voiceAnnouncements(str) {
  / / baidu speech synthesis: https://tsn.baidu.com/text2audio or use the new address
  var url =
    'http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=5&text=' +
    encodeURI(str);
  var n = new Audio(url);
  n.src = url;
  n.play();
}
voiceAnnouncements('Autumn mountain road rare, often riders higher or lower; Now the lane is still there, no old drivers. The driver's skill is still good, the front end of the group is not lonely; Borrow five hundred years to the day, oath to lead each line. `);
// We tried a few ways to change the female voice, but they all failed...
voiceAnnouncements('Wow, the code is really good, you can really show! `);
Copy the code
  • Parameter description:

    • LAN: specifies a fixed value en. Select a language. Currently, only the Chinese and English modes are available. Enter a fixed value en
    • Ie: indicates the encoding mode
    • SPD: The speed ranges from 0 to 9. The default speed is 5
    • Text: Synthesized text, using UTF-8 encoding. Less than 512 Chinese characters or English digits. (After the text is converted to GBK in Baidu server, the length must be less than 1024 bytes)
  • React Native Text-To-Speech library for Android and iOS

  • Voice control of your own website annyang: A tiny JavaScript Speech Recognition library that lets your users control your site with voice commands.annyang has no Dependencies, weighs just 2 KB, and is free to use and modify under the MIT license.

Type 13: What if the out-of-focus event conflicts with the click event?

  • Scene:

    • Blur and click in the dropdown conflict.
    • Conflict between blur and click: the floating layer appears below the input value. The floating layer is hidden when the input value is out of focus. Clicking the floating layer entry triggers a search and hides the floating layer;
    • Problem: When clicking on the floating layer, because the out-of-focus event is triggered first, the floating layer hides the logic execution, so the onClick event logic of the floating layer cannot be executed

// Click the item in the popover to search
handleSearch = (activeSearch) = > {
  console.log(activeSearch);
  this.setState({ visible: false });
}

// Get the focus and display the popover when there is a value
onFocus = () = > {
  if (this.state.keyword) {
    this.setState({ visible: true}); }}// Display a popover when input and value are present
onChange = (e) = > {
  this.setState({
    keyword: e.target.value,
    visible:!!!!! e.target.value }) }// Lose focus to hide the popover
onBlur = () = > {
  if (this.state.keyword) {
    this.setState({ visible: false}); }}render() {
  const { keyword, visible } = this.state;
  return (
    <div>
      <Input
        allowClear
        addonBefore={<Icon type="user" />} placeholder=" style={{width: 0.0001pt; width: 0.0001pt; {this.onfocus} onChange={this.onchange} onBlur={this.onblur} /> {this.onblur} visible && keyword &&<div className={styles.SearchSelect}>
          {
            showOptions.map(item => (
              <div
                onClick={()= > this.handleSearch(item)}
                className={styles.item}
                key={item.key}
              >
                <div>{item. Label}, {keyword}</div>
              </div>))}</div>
      }
    </div>
  );
}
Copy the code
  • Solution:

    • Method 1: Set a delay for the out-of-focus event

      onBlur = () = > {
        if (this.state.keyword) {
          setTimeout(() = > {
            this.setState({ visible: false });
          }, 300); }};Copy the code
    • Method 2: Use onMouseDown instead of onClick

      • Mousedown event: The mouseDown event occurs when the mouse pointer moves over an element and the mouse button is pressed, so it executes before the out-of-focus event.
      • Mouseup event: A mouseup event occurs when the mouse button is released on an element.

Formula 14: How to add without adding, subtracting, multiplying or dividing — bit operations make your code more efficient

  • JavaScript bit operators

Bit operation is based on binary, how to quickly obtain binary can refer to formula 10.

  • Add without adding, subtracting, multiplying or dividing

    function add(a, b) {
      let sum;
      let add1;
      while(b ! =0) {
        / / or
        sum = a ^ b;
        / / and shift to the left
        add1 = (a & b) << 1;
        a = sum;
        b = add1;
      }
      return a;
    }
    Copy the code
  • JS bitwise operators

    • Use the & operator to determine the parity of a number (just remember the results of the & operation of 0 and 1 with 1) :

      • Even &1 = 0
      • Odd &1 = 1
    • Use ~ ~ > >, < < > > >, | to integer:

      • ~~Math.PI: 3 (take the reverse by bit and then take the reverse)
      • Math.PI>>0.Math.PI<<0.Math.PI>>>0: 3 (move 0 bits to the left or to the right,>>>Not available for negative numbers)
      • Math.PI|0: 3. Xor by bit
    • Use <<,>> to calculate multiplication and division:

      • Moving an integer to the left by n bits is equivalent to multiplying by 2 to the n;
      • To the right is the same thing as dividing by 2 to the n, and rounding down
    • Use ^ to complete the comparison of two numbers:! (a ^ b)

    • Use ^ to complete the exchange of values: see Equation 15

    • Use &, > > | to complete the RGB values and conversion between hexadecimal color values

      • Hexadecimal color values to RGB:

        function hexToRGB(hex) {
          hex = hex.replace(The '#'.'0x');
          let r = hex >> 16;
          let g = (hex >> 8) & 0xff;
          let b = hex & 0xff;
          return 'rgb(' + r + ', ' + g + ', ' + b + ') ';
        }
        hexToRGB('#cccccc'); / / RGB (204204204).
        Copy the code
      • RGB to hex color values:

        function RGBToHex(rgb) {
          let rgbArr = rgb.split(/[^\d]+/);
          let color = (rgbArr[1] < <16) | (rgbArr[2] < <8) | rgbArr[3];
          return The '#' + color.toString(16);
        }
        RGBToHex('RGB (204204204).); // #cccccc
        Copy the code

Resources: JavaScript bit operators

Formula 15: boring brain teaser, N ways to exchange the value of two variables a and B without resorting to the third variable

  • Method one: add and subtract

    a = a + b;
    b = a - b;
    a = a - b;
    Copy the code
  • Method two: bit operation

    a ^= b;
    b ^= a;
    a ^= b;
    Copy the code
  • Method three: object or array

    a = { a, b };
    b = a.a;
    a = a.b;
    // a = [a, b];
    // b = a[0];
    // a = a[1];
    Copy the code
  • Method 4: ES 6 deconstructs the assignment

    [a, b] = [b, a];
    Copy the code
  • Option 5: Operator precedence

    a = [b, (b = a)][0];
    Copy the code

Resources: Exchange the values of a and B without the use of a third variable

How to open and operate another TAB page from the current page in the browser

if (window.customeWindow) {
  window.customeWindow.close();
}
window.customeWindow = window.open();
window.customeWindow.document.write(

'

); window.customeWindow.document.write(

'

); window.customeWindow.document.write('And then add something else. '); window.customeWindow.document.close(); // The continuous append input ends window.customeWindow.document.write('Haha, now it's just me on the page! '); window.customeWindow.document.write("> ); Copy the code

Resources: BRAFT EDITOR Preview of rich text EDITOR

Type 17: The products should be sorted according to Chinese pinyin order?

  • usestringObject.localeCompare(target)Methods The Chinese characters are sorted in alphabetical order
var array = ['Shanghai'.'Beijing'.'hangzhou'.'in guangdong'.'shenzhen'.'xi 'an'];
The localeCompare() method returns a number indicating whether a reference string is before or after the sort order or the same as the given string.
array = array.sort((item1, item2) = > item1.localeCompare(item2));
[" Beijing ", "Guangdong "," Hangzhou ", "Shanghai "," Shenzhen ", "Xi 'an "]
Copy the code

Resources: String. Prototype. LocaleCompare ()

  • An array of objects is sorted by another array
sortFunc = (propName, referArr) = > (prev, next) = >
  referArr.indexOf(prev[propName]) - referArr.indexOf(next[propName]);
// Order persons by age
const age = [33.11.55.22.66];
const person = [
  { age: 55.weight: 50 },
  { age: 22.weight: 42 },
  { age: 11.weight: 15 },
  { age: 66.weight: 56 },
  { age: 33.weight: 68},]; person.sort(sortFunc('age', age));
/ / the result:
/ / /
// {"age": 33,"weight": 68},
// {"age": 11,"weight": 15},
// {"age": 55,"weight": 50},
// {"age": 22,"weight": 42},
// {"age": 66,"weight": 56}
// ]
Copy the code

Why does this code report error, said good semicolon can be omitted?

console.log(123) [(12.2)].filter((item) = > item > 3);
// Uncaught TypeError: Cannot read property '2' of undefined
// at <anonymous>:2:1
Copy the code
  • Semicolon inference: A semicolon inference in compiler principles that allows programmers to omit unnecessary semicolons during programming.
  • JavaScript has an Automatic Semicolon Insertion mechanism, called ASI. ASI means that the compiler understands exactly what the programmer is doing and doesn’t insert semicolons.
  • The browser engine’s Parser (which converts JS source code to AST) always parses symbol streams before and after newlines as a single statement (multi-line comments with newlines are equivalent to newlines);
  • So in the eyes of Parser, the above code looks like this:
    • Console. log(123)[12,2].filter(item => item > 3).console.log(123)No return value, eitherundefined;
    • [12, 2]Square brackets in are treated as readsconsole.log(123)Property in the return value2, similar to fetching the elements of an array by subscript;
    • Why take attributes2?12, 2Is a comma expression whose value is the rightmost “2”, so the above error message makes sense.
  • Semicolons that cannot be omitted:
    • The semicolon in the header of the for loop
    • A semicolon that exists as an empty statement
    • In order to[, (, +, -, and /A semicolon before a statement that begins with five characters

ASI (Automatic Semicolon Insertion)

This article is posted on my personal blog, welcome corrections and star.