DD weekly front seven questions detailed explanation – issue 4

Series is introduced

You wish the world, I wish you no bugs. Hello everyone! I’m Lin Dull!

Dull shares seven front-end problems every week, and the series is called “DD 7 Questions per week”.

The form of the series is mainly: 3 JavaScript + 2 HTML + 2 CSS, to help us consolidate the front-end foundation.

All topics will also be integrated into the issues of LinDaiDai/ Niubility -coding-js. You are welcome to provide better ideas for solving problems. Thank you 😁.

Take a look at this week’s seven questions.

To the chase

Following function return?

What does the following code output?

function getName () {
  return
  {
    name: 'LinDaiDai'
  }
} console.log(getName()) Copy the code

Automatic Semicolon Insertion method (ASI) Automatic Semicolon Insertion method (IPEC)

According to the ECMAScript standard, some “specific statements” must end with a semicolon. The semicolon indicates the termination of the statement. But sometimes these semicolons can be omitted for convenience. In this case, the interpreter decides for itself where to terminate the statement. This method is called Automatic Semicolon Insertion (ASI). The semicolon is not actually inserted, it’s just a figurative way to explain it.

Return (); return (); return (); return ();

function getName () {
  return;
  {
    name: 'LinDaiDai'
  }
} console.log(getName()) Copy the code

So the end result is undefined.

Github.com/LinDaiDai/n…

Implement a PIPE function

(30-seconds-of-Interviews)

Implement a pipe function as follows:

const square = v= > v * v
const double = v= > v * 2
const addOne = v= > v + 1
const res = pipe(square, double, addOne)
console.log(res(3)) / / 19; addOne(double(square(3)))
Copy the code

Pipe is a pipe that accepts any number of functions and returns a new function, res.

(1) Pipe basic structure

The basic structure of pipe looks like this:

const pipe = function (. fns) {
  return function (param) {}
}
Copy the code

It is itself a function, and then we can use… FNS gets all the function arguments passed in, square, double, etc.

It then returns a function that accepts the parameter param.

(2) The function returned

The rest of the logic comes down to the returned function, where we need to layer param.

OK👌, it’s easy to think of… reduce…

We can use reduce on an array of FNS functions, and reduce starts with the parameter param passed in.

Let’s take a look at the final code:

const pipe = function (. fns) {
  return function (param) {
    return fns.reduce((pre, fn) = > {
      return fn(pre)
    }, param)
 } } Copy the code

The final return is the value processed by all the functions in the FNS array.

Of course, we can also write it more succinctly:

const pipe = (. fns) = > param= > fns.reduce((pre, fn) = > fn(pre), param)
Copy the code

This gives us the pipe function we want:

const square = v= > v * v
const double = v= > v * 2
const addOne = v= > v + 1
const pipe = (. fns) = > param= > fns.reduce((pre, fn) = > fn(pre), param)
const res = pipe(square, double, addOne)
console.log(res(3)) / / 19; addOne(double(square(3))) Copy the code

Github.com/LinDaiDai/n…

How does Babel compile classes?

(Your tree-shaking is not good for eggs)

For the class below:

class Person {
  constructor ({ name }) {
    this.name = name
    this.getSex = function () {
      return 'boy'
 }  }  getName () {  return this.name  }  static getLook () {  return 'sunshine'  } } Copy the code

If you are not familiar with Class or static, you should read the following article: “Why not inherit JS?”

When we are using these Plugins of Babel or preset, there is a configuration property loose which defaults to false in such conditions:

Class compiled:

  • On the wholeClassIt’s going to be encapsulated into oneIIFEExecute function immediately
  • The immediately executed function returns a constructor with the same name as the class
  • Instance properties and methods are defined in constructors (e.gnameandgetSex())
  • Property methods declared inside a class (getName) and static property methods (getLook) will beObject.definePropertySets its enumerable property tofalse

(The following code looks very long, but there is nothing to divide it up)

Compiled code:

"use strict";

function _classCallCheck(instance, Constructor) {
  if(! (instanceinstanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
 } }  function _defineProperties(target, props) {  for (var i = 0; i < props.length; i++) {  var descriptor = props[i];  descriptor.enumerable = descriptor.enumerable || false;  descriptor.configurable = true;  if ("value" in descriptor) descriptor.writable = true;  Object.defineProperty(target, descriptor.key, descriptor);  } }  function _createClass(Constructor, protoProps, staticProps) {  if (protoProps) _defineProperties(Constructor.prototype, protoProps);  if (staticProps) _defineProperties(Constructor, staticProps);  return Constructor; }  var Person = /*#__PURE__*/ (function () {  function Person(_ref) {  var name = _ref.name;   _classCallCheck(this, Person);   this.name = name;   this.getSex = function () {  return "boy";  };  }   _createClass(  Person,  [  {  key: "getName". value: function getName() {  return this.name;  },  }, ]. [  {  key: "getLook". value: function getLook() {  return "sunshine";  },  },  ]  );   return Person; }) ();Copy the code

Why does Babel use object.defineProperty for class processing? Is it any different than using the prototype chain directly?

  • Properties and methods declared through stereotype chains are enumerable, that is, can befor... of...To search for
  • Methods declared inside a class are not enumerable

So, in order to conform to the true semantics of ES6, Babel compiles classes using Object.defineProperty to define prototype methods.

However, by setting Babel loose mode to true, it does not strictly follow ES6 semantics and compiles code in a way that is more consistent with how we normally write code. You can set babelrc as follows:

{
  "presets": [["env", { "loose": true }]]
}
Copy the code

For example, the property methods of the Person class above will be compiled to declare methods directly on the prototype chain:

"use strict";

var Person = /*#__PURE__*/function () {
  function Person(_ref) {
    var name = _ref.name;
 this.name = name;   this.getSex = function () {  return 'boy';  };  }   var _proto = Person.prototype;   _proto.getName = function getName() {  return this.name;  };   Person.getLook = function getLook() {  return 'sunshine';  };   return Person; } ();Copy the code

conclusion

  • Loose is false by default when compiling with Babel, i.e., non-loose mode

  • In either case, the transformed property methods defined inside the class are defined on the constructor’s prototype object; Static properties are defined on constructors

  • Except in non-looser mode, these property methods are handled by the _createClass function, which sets the property’s enumerable value to False via Object.defineProperty()

  • Since Object is used in the _createClass function, there are side effects in non-loose mode, but not in loose mode.

  • UglifyJS in Webpack still considers loose mode as having side effects, while Rollup has the function of “program flow analysis” to better determine whether the code really has side effects, so it will consider loose mode as having no side effects.

    (A side effect is roughly defined as the behavior of a function that affects, or may affect, variables outside the function.)

Github.com/LinDaiDai/n…

Four, JS three kinds of loading the difference

(Answer reference source: front-end performance optimization – page load rendering optimization)

Normal mode

In this case, JS blocks the browser and the browser must wait for index.js to load and execute before it can do anything else.

<script src="index.js"></script>
Copy the code

Async mode

In async mode, JS does not block the browser from doing anything else. It loads asynchronously, and when it finishes loading, the JS script executes immediately.

<script async src="index.js"></script>
Copy the code

Defer the pattern

In the defer mode, JS loads are asynchronous and execution is deferred. When the entire document has been parsed and the DOMContentLoaded event is about to be triggered, the JS files that have been tagged defer will start executing in sequence.

<script defer src="index.js"></script>
Copy the code

From an application point of view, async is usually used when the dependencies between our script and DOM elements and other scripts are not strong; When the script depends on DOM elements and the execution results of other scripts, we choose defer.

Github.com/LinDaiDai/n…

Five, how to let<p> Test space </p>The space between these two words gets bigger, right?

Subject (source: https://github.com/haizlin/fe-interview/issues/2440)

There was an HTML code that looked like this:

<p>Test the blank space</p>
Copy the code

There is a space between the words “test” and “space”, and how to make this space bigger.

Here are two methods:

  • By givingpLabel setword-spacingSet this property to the desired value.
  • Let’s call this space aspanTags are wrapped and then setspanOf the labelletter-spacingorword-spacing.

I treat p and SPAN labels with letter-spacing and word-spacing, respectively:

<style>
  .p-letter-spacing {
    letter-spacing: 10px;
  }
 .p-word-spacing {  word-spacing: 10px;  }  .span-letter-spacing {  letter-spacing: 10px;  }  .span-word-spacing {  word-spacing: 10px;  } </style> <body>  <p>Test the blank space</p>  <p class="p-letter-spacing">Test the blank space</p>  <p class="p-word-spacing">Test the blank space</p>  <p>test<span class="span-letter-spacing"> </span>The blank space</p>  <p>test<span class="span-word-spacing"> </span>The blank space</p> </body> Copy the code

Let’s take a look at the results:


You can see that I use different spacing for p tags for letter-spacing and word-spacing. Letter-spacing magnify the spacing between Chinese characters, but word-spacing does not magnify the spacing between Chinese characters.

The span tag has only one space, so letter-spacing has the same effect as word-spacing.

So we can say for letter-spacing and word-spacing:

  • letter-spacingandword-spacingBoth attributes are used to add whitespace to their corresponding elements.
  • letter-spacingAdd white space between letters, whileword-spacingAdd space between each word.
  • word-spacingNot valid for Chinese.

Github.com/LinDaiDai/n…

How to solve inline-block whitespace problem?

The original code was:

<style>
.sub {
  background: hotpink;
  display: inline-block;
} </style> <body>  <div class="super">  <div class="sub"> The child </div>  <div class="sub"> The child </div>  <div class="sub"> The child </div>  </div> </body> Copy the code

Results as follows:


You can see that there is a gap between each child. There are Spaces or line breaks between inline-block elements, resulting in gaps.

Solutions:

  • “(1) Remove white space in HTML” : Do not wrap elements:

    <div class="super">
      <div class="sub">
    The child  </div><div class="sub">
    The child </div><div class="sub"> The child </div> </div> Copy the code
  • “(2) Set negative margins” : You can use negative margins to fill in the white space. But you need to adjust font size because the width of the white space is related to this property. Take this example:

    .sub {
      background: hotpink;
      display: inline-block;
      font-size:16px;
      margin-left: -0.4 em;
    } Copy the code
  • < font size: 0 > < font size: 0 > < font size: 0 > < font size: 0 > However, if your child has words, you will have to set the font size for the child separately.

  • (4) Notes:

    <div class="super">
      <div class="sub">
    The child  </div><! -- --><div class="sub sub2">
    The child </div><! -- --><div class="sub"> The child </div> </div> Copy the code

Github.com/LinDaiDai/n…

Does that mean that the element is removed from the DOM tree?

No, a DOM tree is a hierarchy of HTML pages. It refers to the relationships between elements, such as my parent wrapped around me and my brother wrapped around me. Such relationships are called hierarchy.

The document stream is like a queue, I’m supposed to be in the queue, but I’m out of the queue, but my relationship with my father, my brother, my son is still there.

Github.com/LinDaiDai/n…

Refer to the article

Knowledge is priceless, support original.

Reference article:

  • JavaScript ASI Mechanism in Detail
  • “The difference between letter-spacing and word-spacing”

After the language

You wish the world, I wish you no bugs. So much for this article.

You may spend 48 hours a week at work 💻, 49 hours at sleep 😴, and maybe another 20 minutes at 7 questions, which accumulate over a long period of time. I believe we can all witness each other’s growth 😊.

What? You ask me why the series is called DD? Because dull ah, ha ha 😄.

The guy who likes “Lin Dull” also wants to follow Lin dull’s official account LinDaiDai or scan the following QR code 👇👇👇.


I will update some front-end knowledge content and my original article 🎉 from time to time

Your encouragement is the main motivation for my continuous creation 😊.

This article is formatted using MDNICE