The problem the forerunner

  • html5What are the features? [HTML]
  • <title>and<h1>The difference between?<b>and<strong>The difference between?<i>and<em>The difference between? [HTML]
  • <li>What is the invisible white space between elements? How to solve it? “CSS”
  • css3What are the new features? “CSS”
  • Why are there additionsBigIntWhat are the caveats when using this data type? 【 JS data type 】
  • Object.assignWhat’s the difference from expansion syntax? 【 JS Basics 】
  • let,constandvarThe difference between? 【 JS Basics 】
  • v-ifandv-showThe difference between? 【 Vue 】
  • v-modelHow to do that? 【 Vue 】
  • handwrittenPromise.then[Handwritten code]
  • handwrittenPromise.all[Handwritten code]
  • handwrittenPromise.race[Handwritten code]
  • Output result (Promise related)
  • Recover IP address [algorithm]

Knowledge comb

hml5What are the new features?

  • Semantic tags: Header, footer, nav, article, section, aside, etc

  • Media tags: Audio, Video, Source (Provide multiple media sources for selective playback by browser)

    <audio controls>
        <source src="/i/horse.ogg" type="audio/ogg">
        <source src="/i/horse.mp3" type="audio/mpeg">
        Your browser does not support the audio element.
    </audio>
    Copy the code
  • The form tag

    • newtypeThe value can be Email, URL, number, search, range, color, time, data, datatime, datatime-local, week, or month
    • Form attributes: placeholder (input hints), Autofocus (autofocus), and AutoComplete (autocomplete) have two optional values, ON and off, provided that the form must specify the name attribute, which will take effect only after the form is submitted. The result is that the form will automatically fill in the historical input values and display the historical submission values when entered), required (mandatory), Pattern (defining matching regular rules), multiple (multiple forms can store multiple files or mailboxes), and form (specifying the ID of the form to which it belongs).
    • Form events: onInput, onInvalid (triggered when authentication fails)
  • Progress bar, gauge

    • : indicates the progress of a task (IE and Safari are not supported), Max indicates the total amount of a task, and value indicates the completed amount. If the value is not set, the progress bar will automatically scroll and animation will appear. And input[type=”range”] except for style differences, input is of course user-friendly.

    • : Measures data within a given range. The default value is 0-1. Then you can use low and high to specify the low-value and high-value regions of the metric: Values between [min-low] and [low-high] are low-value areas with low visual effects (Chrome metric color changes to orange), then values between [low-high] are normal areas, and (high, Max] is high-value areas with visual changes (Chrome metric color changes to red).

      For example, we know that PE (price/earnings ratio) is often used as an index valuation indicator. When the historical percentile of equal weight is in the range of 30%-70%, it is a normal area. If the historical percentile of equal weight is less than 30%, it is considered that the index is in the trough area with good investment value.

      <p>PE index (percentile)</p>
      <div>14%<meter min="0" max="100" low="30" high="70" value="14">14%</meter>Belong to the zone of underestimation</div>
      <div>45%<meter min="0" max="100" low="30" high="70" value="45">45%</meter>Belong to normal zone</div>
      <div>88%<meter min="0" max="100" low="69" high="70" value="88">88%</meter>Belong to the overestimated region</div>
      Copy the code

      Effect:

    In addition, you can also set the optimun attribute to mark the interval where the optimal value is located. For example, if optinum=”10″ is set in the case, it indicates that the underestimated region belongs to the preferred region. This attribute is only a logical indicator and has no special effect, that is, the interval where the optimal value is located is the logical preferred region (expected region). .

  • DOM query operation: document. QuerySelector, document. QuerySelectorAll

  • Web storage: localStorage, sessionStorage

  • Others: Draggable, Canvas, vector SVG, geolocation, communication protocol Websocket, instant history API, etc.

<title>and<h1>The difference between?<b>and<strong>The difference between?<i>and<em>The difference between?

The

element defines the title of the document, while

represents a well-defined title that has a significant impact on the fetching of page information.

Both the and pages are in bold, but the is also emphasized. Similarly, the physics of < I > and are italic, but also has an emphasis on meaning.

Conclusion is, h1, strong, em labels have logic state, such as the title, and I only have physical state, b has the effect of the tag and semantic logic state is consistent, the logic effect also pointed to the search engines catch emphasis, and physical state is the effect of bringing these logical label, Changing its default style does not affect its logic.

<li>What is the invisible white space between elements? How to solve it?

The default display attribute for the

  • element is list-item. Sometimes we need to set
  • to inline display:
  • <ul class="hero">
      <li>Jinx</li>
      <li>Yasuo</li>
      <li>Riven</li>
      <li>Teemo</li>
    </ul>
    Copy the code
    .hero li {
      display: inline;
    }
    .hero li:nth-child(odd)  {
      background: #21c96e;
    }
    .hero li:nth-child(even) {
      background: #ff0000;
    }
    Copy the code

    The display should look something like this:We found thatliThere’s an extra space between the tags. Actually, this one isn’tliThe problem of label itself, but clearThe browser renders the white space character (space, newline, Tab, etc.) in the middle of the inline label as a spaceTherefore, the top<li>Placed on a single line, whitespace characters between elements are rendered as Spaces.

    Solutions:

    • will<li>Write on one line. But this is not beautiful, may also be HTML formatting plug-in formatting after the line, not recommended.
    • Set up theliFloating stylefloat: left;. Disadvantages: Bad for control in some scenarios.
    • Sets the character size of the parent element to 0, that isfont-size: 0;And then set it separatelylithefont-size. The purpose of this is to place whitespace charactersfont-sizeThe character size of the element is set to 0, and it is not visible, but if the parent element is notliThe element also has other text elements that need to be set separatelyfont-sizeProperties, it’s a little bit more cumbersome.
    • Sets the character spacing property of the parent elementletter-spacing: -5px;, because the space roughly occupies5pxTo “squeeze” these Spaces together, set the character spacing to negative, but again, set the child elements separately<li>theletter-spacing:normal;

    CSS3What are the new features?

    • Added various CSS selectors, such as :not()

    • Rounded corner attribute: border-radius

      <div style=" width: 50px; height: 50px; background: #29a2b1; border-radius: 10px; "></div>
      Copy the code
    • Multi-column layout: Multi-column layout

    • Shadows and Reflections

      <div style=" width: 50px; height: 50px; background: #29a2b1; border-radius: 10px; box-shadow: 10px 10px 5px #cca; "></div>
      Copy the code

      Grammar:

      box-shadow: h-shadow v-shadow blur spread color inset;

      1. h-shadow: Horizontal shadow offset (required)
      2. v-shadow: Vertical shadow offset (required)
      3. blur: Fuzzy distance
      4. spread: Shadow size
      5. color: Shadow color
      6. inset: If no value is specifiedinset, the default shadow is outside the border, that is, the shadow spreads out. useinsetKeywords cause shadows to fall on the inside of the box, making it look like the content has been lowered. The shadow is inside the border (even if it’s transparent), above the background, and below the content.

      In addition, box-sahdow can accept multiple values, separated by commas, which is the effect of setting multiple shadow values to overlap.

      Box-reflect is an attribute in the experiment, which can create a reflection effect. For more information, please refer to -webkit-box-reflect-mDN

    • Text-shadow

    • Text-decoration

    • Linear gradient

    • Offset (transform)

    • Added rotation, zooming, positioning, tilting, animation, multiple backgrounds and more

    Why newBigIntThis data type? What are the usage details?

    MAX_SAFE_INTEGER indicates the integer 2^ 53-1, beyond which numeric operations lose precision.

    This is because JS uses a double precision floating point number, that is, a 64-bit fixed length to store a number. In binary scientific notation, it is divided into three parts: For integers, 2^0 is equal to 00(*11)0(*51)1, 2^1 is equal to 00(*11)0(*50)10. That is, every time the exponent increases by 1, The 25 significant bits can only hold up to 2^52 exponents, but 0 can also be replaced by 1, so 2^25 + n can hold up to 2^52 exponents. 2 to the 53-1, because once you get past 53 you need 53 significant digits, but now you only have 52 digits, so you can just subtract 1 from that limit. Similarly, for decimals, the exponential part is actually a negative number. Integers can be subtracted by 1, but decimals cannot, so decimals also have a minimum precision: 2^-52, which we can obtain using Math.Epsilon.

    MAX_SAFE_INTEGER (2^ 53-1); MAX_SAFE_INTEGER (2^ 53-1); MAX_SAFE_INTEGER (2^ 53-1) The minimum accuracy is math.epsilon (2^-52).

    Therefore, for integers that exceed the maximum safe number, the calculation may lose progress, as in 0.1 + 0.2! = 0.3, integers out of storage will lose precision, so **BigInt** is a built-in object that provides a way to represent integers greater than 2^ 53-1. This was originally the largest Number that could be represented as Number in Javascript. BigInt can represent an arbitrarily large integer. You can define a BigInt by adding n to an integer literal, such as 10n, or by calling BigInt().

    Note that:

    • In addition to the general number operators can be used directly, becauseBigIntIs a signed integer, so the unsigned shift operator is not supported>>>.
    • Single entries are not supported+Operations, such as+2nIt throws an error. This isFor compatibility with ASM.js.
    • When usingBigInt, the operations with decimals will beinteger. Such as5n / 2n == 2n.
    • BigIntandNumberNot exactly equal, but loosely equal. Such as5n == 5istrue, but5n === 5isfalse.
    • BigIntandNumberCan not perform numerical operations between, but can perform comparison operations.

    What’s the difference between object. assign and expand? What are the things to look out for?

    The object.assign () method is used to assign the values of all enumerable properties from one or more source objects to the target Object and to return the target Object.

    Spread syntax: array expression or string can be expanded at the syntactic level during function call/array construction; You can also construct literal objects by expanding the object expression key-value.

    • Function call: myFunction(… iterableObj);
    • Literal array constructs or strings:[...[1, 2, 3], '4', ...'hello', 6];The return value is an array [1, 2, 3, "4", "h", "e", "l", "l", "o", 6].
    • When constructing literal objects, clone or copy properties (a new feature in the ECMAScript 2018 specification) : Let objClone = {… obj };

    Actually, expand the syntax and the object.assign () calendar layer).

    In both cases, you can expand an iterable and copy it to the target Object. The expansion syntax is more flexible, allowing you to express residual variables in function arguments. However, for non-iterable objects such as null and undefined, the expansion will raise an error. It’s more secure to use.

    let,constandvarThe difference between?

    Let and const are new block-level scope variable declaration keywords in ES6. Since they are block-level scope, let and const do not have variable promotion and must be declared in advance before use. Moreover, block-level scope cannot be repeatedly declared in the same scope, which makes the use of variables more specific and rigorous compared with var. Let differs from const in that const is used to represent constants and can only be assigned at declaration time. Once assigned, it cannot be reassigned.

    In order to use variable declaration keywords, it is recommended to use const in preference, and to use let instead of var for variables whose values need to be changed.

    v-ifandv-showThe difference between

    Vue’s two conditional render instructions:

    • v-ifWill be generated or deleted, depending on the instruction valuevnodeNode that needs to be deleted or rebuiltdomNodes are expensive, so do not use this directive for frequently switching elements to show hidden
    • v-showWill directly generatevnodeAnd the correspondingdomNode, and then switch elements based on the instruction valuedisplayShow or hide.

    V-if is “true” conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during the switch. V-if is also lazy: if the condition is false during initial rendering, nothing is done, and the conditional block does not start rendering until the condition is true for the first time. V-show, by contrast, is much simpler, with elements always rendered regardless of initial conditions and simply switched based on CSS.

    In addition, v-if can be used with v-else.

    v-modelHow is it done?

    V – is the model form controls often use a two-way data binding instruction, the data binding this instruction will be binding and forms of value, the value, when the value changes, form values will also change, on the other hand, when the user to change the form values, data binding will also change, that is to realize the two-way binding a simple instructions.

    In effect, v-model is a combination of V-bind :value and V-on :input.

    V-models typically work only when used in form elements:

    • <input>
    • <select>
    • <textarea>
    • Components (in components)

    We know the principle of V-Model, we can also write a custom instruction of the same function v-my-Model.

    For the definition of custom directives, please refer to the official documentation: Custom Directives.

    Vue.directive('my-model', {
        inserted: function(el, binding, vnode) {
            el.value = binding.value;
            // Listen for events to update bound expressions
            el.addEventListener('input'.function(evt){
                vnode.context[binding.expression] = evt.target.value;
            });
        },
        update: function(el, binding, vnode) {
            // Update the form value when the expression is updatedel.value = binding.value; }});Copy the code

    Note: The context object of the virtual node has a reference to the instruction expression, which can be directly assigned to trigger the expression update of the Vue instance.

    Written Promise. Then

    Promise.then is the key to the Promise chain invocation, which returns a new Promise object.

    The method takes two arguments, a callback in the Promise success state and a callback in the failure state.

    The key to promise. then lies in the return value of the callback function, which determines the state and result of the returned Promise object.

    • Returns a value, sothenThe returned Promise will become the accepted state, and the returned value will be used as the parameter value of the callback that accepts the state.
    • No value is returned, thenthenThe returned Promise will be the accepted state, and the accepted state callback will take the value ofundefined.
    • Throw an error, thenthenThe returned Promise will be the rejection state, and the thrown error will be the parameter value of the rejection state callback.
    • Return a Promise that is already in an accepted state, thenthenThe returned Promise also becomes the accepted state, and the value of the Promise’s accepted state callback is used as the value of the returned Promise’s accepted state callback.
    • Return a Promise that is already in the reject state, thenthenThe returned Promise also becomes the rejection state, and the value of the Promise’s rejection state callback is used as the value of the returned Promise’s rejection state callback.
    • Returns an undetermined state (pending), thenthenThe state that returns a Promise is also undefined, and its final state is the same as the final state of that Promise; At the same time, the callback that it calls when it goes to its final state is the same as the callback that the Promise calls when it goes to its final state.

    If the return value is a Promise object, then return the Promise object directly. If not, then will return a fulfilled Promise and set the return value to the state value of the new Promise object. If the callback returns an implementation error, the returned state of the new Promise object will change to Rejected.

    Before we can implement promises.then, we need to implement our own Promise objects first. For details, see the exercise notes from the previous day: Handwritten Promises.

    Here we write the myPromise.then section directly:

    /**
     * Promise.then
     * @param {Function} onFulfilled 
     * @param {Function} onRejected 
     */
    MyPromise.prototype.then = function(onFulfilled, onRejected) {
        const THIS = this;
        const SELF = new MyPromise((resolve, reject) = > {
            // Successful callback
            function fulfilledCall(res) {
                try {
                    const callRes = typeof onFulfilled === 'function' ? onFulfilled(res) : undefined;
                    checkBackSelf(callRes);
                    callRes instanceof MyPromise ? callRes.then(resolve, reject) : resolve(callRes);
                } catch(err) { reject(err); }}// Failed callback
            function rejectedCall(res) {
                try {
                    const callRes = typeof onRejected === 'function' ? onRejected(res) : undefined;
                    checkBackSelf(callRes);
                    callRes instanceof MyPromise ? callRes.then(resolve, reject) : reject(callRes);
                } catch(err) { reject(err); }}// return to self test
            function checkBackSelf(newPro) {
                if(newPro === SELF) {
                    throw new TypeError('Chaining cycle detected for promise #<Promise>');
                }
                return false;
            }
    
            if(THIS.state === PromiseState.FULFILLED) {
                fulfilledCall(THIS.data);
            } else if(THIS.state === PromiseState.REJECTED) {
                rejectedCall(THIS.err);
            } else {
                // Wait for execution
                this.fulfilledCalls.push(fulfilledCall);
                this.rejectedCalls.push(rejectedCall); }});return SELF;
    };
    Copy the code

    Reference:

    • Promise.prototype.then() – MDN

    Written Promise. All

    Promise. All accepts an iterable of Promise and returns an instance of Promise. If all the iterables return a depressing state, then the returned Promise state will also be successful. The return value is an array of all iterable Promise success values. If one of the iterables has a rejected Promise state, the returned Promise instance will return the failed state of the first failed Promise.

    It is important to note that on success, the success status values collected are in the same order as the iterables.

    Such as:

    const promise1 = Promise.resolve(3);
    const promise2 = 42;
    const promise3 = new Promise((resolve, reject) = > {
      setTimeout(resolve, 100.'foo');
    });
    Promise.all([promise1, promise2, promise3]).then((values) = > {
      console.log(values);
    }, (err) = > {
       console.log(err);
    });
    // expected output: Array [3, 42, "foo"]
    
    Copy the code

    Resolve (2) is automatically converted to promise.resolve (2).

    If there is still confusion, we directly look at the handwritten source code is very clear:

    const promiseAll = function(可迭代) {
        return new Promise((resolve,reject) = > {
            const reses = [];
            const keys = Object.keys(iterable);
            const len  = keys.length;
            let resolveCount = 0;
            for(let i = 0; i < len; i++) {
                Promise.resolve(iterable[keys[i]]).then(res= > {
                    reses[i] = res;
                    if(len == (++resolveCount)) { resolve(reses); }},(err) = >{ reject(err); }); }}); }Copy the code

    Note that we use reses[I] for replication instead of a direct push to ensure that the success status of the collection is consistent with the iteration order.

    Written Promise. Race

    The promise.race (iterable) method returns a Promise that is resolved or rejected once a Promise in the iterator is resolved or rejected.

    Race stands for “race,” and this is how the API is used, to make promises in an iterable run in parallel, with the first person to return a result directly returning that object’s state.

    const promiseRace = function(可迭代) {
        return new Promise((resolve,reject) = > {
            for(let promise of iterable) {
                Promise.resolve(promise).then((res) = > {
                    resolve(res);
                }, (err) = > {
                    reject(err);
                });
            };
        });
    }
    Copy the code

    Output results (Promise related)

    Code snippet:

    const promise = new Promise((resolve, reject) = > {
        resolve('success1');
        reject('error');
        resolve('success2');
    });
    promise.then((res) = > {
        console.log('then:', res);
    }).catch((err) = > {
        console.log('catch:', err);
    })
    Copy the code

    Once the Promise state switch is not fulfilled or rejected, the state will not change again. Therefore, executing the state switch function several times will only trigger the first time, so the printing result is:

    then: success1
    Copy the code

    Code snippet:

    Promise.resolve(1)
      .then(2)
      .then(Promise.resolve(3))
      .then(console.log)
    Copy the code

    The return value of the Promise. Then callback is returned as a new Promise. If the callback does not return a value, a padding-state Promise is returned.

    In addition, if the argument to promise.then is not a function, the current Promise is returned directly.

    1. First of all,Promise.resolveReturns afulfilledThe state of thePromise
    2. Due to the2Is not a function, so returns the current directlyPromise“, which is the first sentencePromise.resolve(1)“Is equivalent to this sentencethenCall is invalid
    3. Notice that the third line of code is aPromiseObject, again not a callback function, skip
    4. console.logIs an executable function that prints the currentPromiseThe state of the value1

    So the output is:

    1
    Copy the code

    Recover IP address

    Given a numeric string representing an IP address, return all valid IP addresses that can be obtained from S. You can return the answers in any order. A valid IP address consists of four integers (each integer is between 0 and 255, and cannot contain a leading 0), separated by a hyphen (.). For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses, but "0.011.255.245", "192.168.1.312" and "[email protected]" are invalid IP addresses. Example 1: Input: s = "25525511135" Output: ["255.255.11.135","255.255.111.35"] Example 2: Input: s = "010010" Output: ["0.10.0.10","0.100.1.0"] Example 3: Output: input: s = "0000"/" 0.0.0.0 "example 4: input: s =" 101023 "output: [" 1.0.10.23", "1.0.102.3", "10.1.0.23", "10.10.2.3", "101.0.2.3]" tip: S consists only of numbers.Copy the code

    This problem requires enumerating all possible values, that is, enumerating all the answers that meet the conditions. The commonly used enumeration search algorithm is the backtracking algorithm. Backtracking is a kind of optimal search method, which searches forward according to the optimal conditions to reach the target. However, when a certain step is explored, it is found that the original choice is not good or fails to reach the target, so it takes a step back to make a new choice. The technology of going back and going again when there is no way is called backtracking method, and the point in a certain state that meets the backtracking condition is called “backtracking point”. Backtracking can be used for many complex, large-scale problems, and has the good name of being a “general solution.”

    We are asked to find four IP addresses, each consisting of an integer between [0, 255] and no leading 0. The normal way to think about it is to look for the first segment, then look for the second segment, and so on, and if you find the fourth segment and the string is just iterated, then you get a solution. Based on this idea, for four IP addresses, the violent solution only needs to list three layers of for loop to iterate all the cases, but this is only for the case with a small number of segments. If there are too many segments, the violent solution will be difficult, so we use the backtracking algorithm.

    The idea of the backward step is the same as the brute force solution: we need to find a segment by segment, so we need parameters like: segment subscript segId, find the start position segStart. We use the recursive function DFS (s, segId, segStart) to indicate that we are looking for segment segId + 1 from position S [segStart] in string s(segId starts at 0).

    / * * *@param {string} s
     * @return {string[]}* /
    var restoreIpAddresses = function(s) {
        const totalSeg = 4; // Find the total number of segments
        const res = [];
        const segment = [];
        dfs(s, 0.0);
        return res;
    
        /** * string back to the search segment *@param {string} s 
         * @param {number} segId 
         * @param {number} segStart 
         */
        function dfs(s, segId, segStart) {
            // If the number of segments is queried and the string is searched, the condition is met
            if(segId === totalSeg && segStart === s.length) {
                res.push(segment.join('. '));
                return;
            }
            // The number of search segments has exceeded or the number of string search segments has exceeded
            if(segId >= totalSeg || segStart === s.length) {
                return;
            }
            // In the special case, when the search start is 0, this section can only be 0
            if(s[segStart] === '0') {
                segment[segId] = 0; // Record segment values
                dfs(s, segId+1, segStart + 1);
            }
            // In normal cases, each possibility is iterated through the current paragraph and the next paragraph is recursively found
            let segValue = ' ';
            for(let i = segStart; i < s.length; i++) {
                segValue += s[i];
                const val = +segValue;
                if(val > 0 && val <= 255) {
                    segment[segId] = val;
                    dfs(s, segId + 1, i + 1);
                } else {
                    // Due to the continuity of the address, once there is a segment that does not meet the condition, it will not be satisfied again
                    break; }}}};Copy the code