This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!

preface

Native built-in a lot of API, the role is similar, but also different, understand the difference, master the front-end foundation, is to cultivate the upper level, become the front-end senior engineer of the necessary knowledge, let us classify and summarize together, grow together.

Functions that are familiar but unfamiliar to you

Properties forkeys.getOwnPropertyNames.getOwnPropertySymbols

Object.keys

Returns an array of self-enumerable properties of a given object in the order returned by a normal loop through the object.

Object.getOwnPropertyNames

Returns an array of the property names of all the properties of the specified object (including non-enumerable properties but not including the Symbol value as the name).

Object.getOwnPropertySymbols

An array of all Symbol properties for a given object itself.

Reflect.ownKeys

Returns an array of the property keys of the target object itself. Equal to the Object. GetOwnPropertyNames (target). The concat (Object. GetOwnPropertySymbols (target))

example

const symbolSalary = Symbol.for("salary");
const symbolIsAnimal = Symbol.for("isAnimal");
const symbolSay = Symbol.for("say");

function Person(age, name){
   this.age = age;
   this.name = name;

   this.walk = function () {
       console.log("person:walk"); }}// Prototype method
Person.prototype.say = function(words){
   console.log("say:", words);
}
Person.prototype[symbolSay] = function(words){
   console.log("symbolSay", words);
}

// Prototype properties
Person.prototype[symbolIsAnimal] = true;
Person.prototype.isAnimal = true;

const person = new Person(100."Programmer");

person[symbolSalary] = 6000;
person["sex"] = "Male";

// Sex cannot be enumerated
Object.defineProperty(person, "sex", {
   enumerable: false
});

Object.defineProperty(person, symbolSalary, {
   enumerable: false.// Invalid Settings
   value: 999
});

const keys = Object.keys(person);
const names = Object.getOwnPropertyNames(person);
const symbols = Object.getOwnPropertySymbols(person);
const ownKeys = Reflect.ownKeys(person);

console.log("keys", keys);  // [ 'age', 'name', 'walk' ]
console.log("getOwnPropertyNames", names); // [ 'age', 'name', 'walk', 'sex' ]
console.log("getOwnPropertySymbols", symbolSalary); // [ Symbol(salary) ]
console.log("ownKeys", ownKeys); // [ 'age', 'name', 'walk', 'sex', Symbol(salary) ]


console.log("-- -- -- -- -- -- -- --")
console.log(person.isAnimal);  // true
console.log(person[symbolIsAnimal]); // true
console.log(person[symbolSalary]);  / / 999
person[symbolSay]("hello world"); // symbolSay hello world
person.say("hello world"); // say: hello world
person.walk(); // person:walk
Copy the code

conclusion

  1. Object.keys: returns all enumerable keys, which is an enumerable: true attribute. It does not include the attribute key whose Symbol value is the name.

  2. Object. GetOwnPropertyNames: returns the Object all their key attributes, including an enumerated attribute but does not include key Symbol value as the name of the attribute.

  3. Object. GetOwnPropertySymbols: method returns a given Object itself all the key Symbol attribute array.

  4. Reflect.ownKeys: Returns an array of the target object’s own property keys. Equal to the Object. GetOwnPropertyNames (target). The concat (Object. GetOwnPropertySymbols (target).

Node position relationNode.contains.Node.compareDocumentPosition

Node.compareDocumentPosition

Compares the position of the current node with another node in any document

Grammar compareMask = node.com pareDocumentPosition (otherNode)

The return value is a bitmask with the following values:

Constant names Decimal value meaning
DOCUMENT_POSITION_DISCONNECTED 1 Not in the same document
DOCUMENT_POSITION_PRECEDING 2 OtherNode precedes node
DOCUMENT_POSITION_FOLLOWING 4 OtherNode comes after node
DOCUMENT_POSITION_CONTAINS 8 OtherNode contains the node
DOCUMENT_POSITION_CONTAINED_BY 16 OtherNode is contained by node
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC 32 To be determined

In some scenarios, more than one bit value may be set. For example, if otherNode was first in the document and included Node, then DOCUMENT_POSITION_CONTAINS and DOCUMENT_POSITION_PRECEDING would both be set, so the result would be 0x0A, which is 10 in decimal terms.

Look at the code: the result is: 20

  1. Child is worth 4 after parent
  2. Child is contained by parent, assigned to 16

4 plus 16 is 20

    <div id="parent">
        <div id="child"></div>
    </div>

    <script>

        const pEl = document.getElementById("parent");
        const cEl = document.getElementById("child");
        console.log(pEl.compareDocumentPosition(cEl));  / / 20

    </script>
Copy the code

Node.contains

Returns a Boolean value indicating whether the incoming node is a descendant of that node

Basic equal compareDocumentPosition | DOCUMENT_POSITION_CONTAINED_BY 16 | | otherNode node contains |

conclusion

  1. CompareDocumentPosition returns numeric, combinatorial data, not only contains, but also before and after information
  2. Contains returns a Boolean value that just tells you whether or not there is an inclusion relationship

Take the textinnerText.textContent

HTMLElement.innerText

Parsing process:

  1. Parse HTML tags;
  2. Parsing and rendering of CSS styles with restrictions;
  3. Convert an ASCII entity to its corresponding character
  4. Eliminate format information (such as \t, \r, \n, etc.) and combine multiple consecutive Spaces into one

Node.textContent

Parsing process:

  1. The HTML tag is removed;
  2. Converts an ASCII entity to the corresponding character.

Note that:

  1. The HTML tags are culled, not parsed, and there is no CSS parsing and rendering, therefore<br/>Such elements are not valid.
  2. Format information is not excluded and consecutive Spaces are combined, so \t, \r, \n, and consecutive Spaces are in effect

example

    <p id="source">
        <style>
            #source {
                color: red;
            }
        </style>
        Take a look at<br>how this text<br>is interpreted
        below.
        <span style="display:none">HIDDEN TEXT</span>
    </p>
    
     <h3>Result of textContent:</h3>
    <textarea id="textContentOutput" rows="12" cols="50" readonly>.</textarea>
    <h3>Result of innerText:</h3>
    <textarea id="innerTextOutput" rows="12" cols="50" readonly>.</textarea>

    <script>
        const source = document.getElementById('source');
        const textContentOutput = document.getElementById('textContentOutput');
        const innerTextOutput = document.getElementById('innerTextOutput');

        textContentOutput.innerHTML = source.textContent;
        innerTextOutput.innerHTML = source.innerText;
    </script>
Copy the code

Look at the results:

conclusion

  1. The innerText is going to parse the CSS,<br/>Valid, eliminate format information (such as \t, \r, \n, etc.), and combine multiple consecutive Spaces into one.
  2. TextContent is going to strip out the HTML tags,<br/>Null and void,\t, \r, \nAnd consecutive Spaces will take effect.

Node valuesvalue , nodeValue

Node.nodeValue

  • fortext.comment, andCDATAFor nodes, nodeValue returns the text content of that node.
  • In the case of an Attribute node, the attribute value for that attribute is returned.

This corresponds to the nodeType values text 3,4,8 in the table below

constant NodeType value describe
Node.ELEMENT_NODE 1 An element node, for example

Node.TEXT_NODE 3 The actual text in Element or Attr
Node.CDATA_SECTION_NODE 4 A CDATASection, such as <! CDATA [[…]] >.
Node.PROCESSING_INSTRUCTION_NODE 7 A ProcessingInstruction (en-US) for XML documents, such as declarations.
Node.COMMENT_NODE 8 A Comment node.
Node.DOCUMENT_NODE 9 A Document node.
Node.DOCUMENT_TYPE_NODE 10 The DocumentType node that describes the DocumentType. For example, for HTML5.
Node.DOCUMENT_FRAGMENT_NODE 11 A DocumentFragment node

value

The value attribute is used to retrieve the value of specific HTMLElement elements. Common elements with a value attribute are:

  • HTMLInputElement <input value="1" />
  • HTMLTextAreaElement <textarea value= "" />
  • HTMLButtonElement <button value= "submit" />
  • HTMLDataElement <data value="21053"> Cherry blossom </data>
  • HTMLSelectElement <select><option value ="volvo">Volvo</option>
  • HTMLOptionElement <select><option value ="volvo">Volvo</option>
  • HTMLParamElement
<object classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" id="Slider1" width="100" height="50">    
     <param name="BorderStyle" value="1" />
</object>
Copy the code
  • HTMLProgressElement <progress value="22" max="100"></progress>

conclusion

  1. NodeValue is the method used to value text nodes, attribute nodes, comment nodes, and so on
  2. Vlaue is the method used to value a particular element node

Nodes copyadoptNode.importNode.cloneNode

Document.adoptNode

Make a copy of a node in an external document, which can then be inserted into the current document.

Document.importNode

Get a node from another Document document. This node and all nodes in its subtree are removed from the original document, and its ownerDocument property becomes the current Document document. You can then insert this node into the current document.

Node.cloneNode

Make a copy of the node.

In factDocumentIs inherited fromNode, also havecloneNodeMethods.

Here’s a question: Document.adoptNode and document.importNode operate on external documents, what happens to the Document where the operation is taking place?

Node.cloneNode has an optional Boolean parameter deep:

  • true: all descendants of the node are also cloned
  • false: only the node itself is cloned.

Pay attention to

  1. cloneNode deepParameters are implemented in different versions of the browser,The default value may be different, so it is highly recommended to write values.
  2. CloneNode clones an element node and copies all its attributes and attribute values, including events bound to the attribute (such as onclick=”alert(1)”), but not those that use the addEventListener() method or Node.onclick = Fn is a dynamically bound event in JavaScript

conclusion

  1. AdoptNode copies from external documents
  2. ImportNode copies and deletes from external documents
  3. CloneNode replicates from this document, both shallow and deep

The parent nodechildNodes , children

Node.childNodes

A collection of child nodes of a node, including element nodes, text nodes, and attribute nodes

ParentNode.children

All that is returned is the collection of element nodes of the node, that is, the node with nodeType 1.

example

Let’s actually look at some code:

    <div id="root">
        1
        <span>2</span>
        3
        <! -- <div></div> -->
        
      
    </div>

    <script>
        const rootEl = document.getElementById("root");
        console.log(rootEl.children);
        console.log(rootEl.childNodes);
    </script>
Copy the code

A screenshot of the result is returned:

The same goes for node. parentNode and node. parentElement.

conclusion

  1. Children returns only element nodes, that is, nodes with nodeType 1
  2. ChildNodes returns nodes of all types

Add a nodeappend.appendChild

node.appendChild

Appends a node to the end of the list of children of the specified parent node

ParentNode.append

Method inserts a set of Node objects or domStrings after the last child of ParentNode. The inserted DOMString object is equivalent to a Text node.

example

We append three nodes at once, two text nodes and one div node.

  <div id="root"></div>
  <script>
    function createEl(type, innerHTML){
        const el = document.createElement(type);
        el.innerHTML = innerHTML;
        return el;
    }
    const rootEl = document.getElementById("root");

    rootEl.append("我们", createEl("div"."Are"), "Good boy");
  </script>
Copy the code

conclusion

  • Parentnode.append () allows appending domStrings, while node.appendChild () only accepts Node objects.
  • Parentnode.append () does not return a value, while node.appendChild () returns the appended Node object.
  • Parentnode.append () can append multiple nodes and strings, while node.appendChild () can append only one Node.

Append is simply too powerful.

Document visibility statusDocument.hidden.Document.visibilityState

document.hidden

Returns a Boolean value indicating whether the page is (true) or (false) hidden.

Document.visibilityState

Returns the visibility of the document, which tells you whether the current document (that is, the page) is behind it, hidden tabs that are not visible, or pre-rendered. The available values are as follows:

  • ‘visible’ : The page content is at least partially visible. This page is in the foreground TAB and the window is not minimized.
  • ‘hidden’ : The page is not visible to the user. The document is in the background TAB or the window is minimized, or the operating system is in the ‘lock screen state’.
  • ‘prerender’ : The page is currently being rendered and therefore not visible. Documents can only start from this state and can never be changed from other values. Note: Browser support is optional.

When the value of this property changes, the VisibilityChange event is submitted to the Document.

example

Let’s print out the current state, and then click on another TAB, and then click back later.

      console.log(
        "visibilityState:".document.visibilityState,
        " hidden:".document.hidden,
      );
      console.log("");
      document.addEventListener("visibilitychange".function () {
        console.log(
          "visibilityState:".document.visibilityState,
          " hidden:".document.hidden
        );
      });
Copy the code

We can use VisibilityChange to monitor when the current page is hidden, to clear the timer or the animation in the page, stop the playback of music videos and so on.

I’ve got an interesting one

  1. Advertising countdown

After you leave, not counting down, will not be cursed to death

  1. Read some agreements

When you leave, stop the countdown

conclusion

  1. Hidden and visibilityState return values are different. One is a Boolean and the other is a string
  2. VisibilityState There is one more stateprerender, whose corresponding hidden value is true
  3. VisibilityState e has related events

A function callcall.apply.bind

Function.prototype.call

Calls a function with a specified value of this and one or more arguments given separately

Function.prototype.apply

Calls a function with the given value of this and the arguments provided as an array (or array-like object)

Function.prototype.bind

Method to create a new function. When bind() is called, this is specified as the first argument to bind(), and the remaining arguments are used as arguments to the new function

example

function sum(. args) {
    const total = args.reduce((s, cur) = > {
        return s + cur;
    }, 0);

    return (this.base || 0) + total;
}

const context = {
    base: 1000
};

const bindFun = sum.bind(context, 1.2);

const callResult = sum.call(context, 1.2.3.4);
const applyResult = sum.apply(context, [1.2.3.4]);
const bindResult = bindFun(3.4);


console.log("call:", callResult);  / / 1010
console.log("apply:", applyResult); / / 1010
console.log("bind:", bindResult); / / 1010
Copy the code

conclusion

For the same reason, you can change the point of this to the called function.

  1. Call: start with the second argument and receive any argument
  2. Apply: The second argument, which must be an array or a class array
  3. Bind: starts with the second argument, accepts any argument, and returns a new function

Note:

  1. Bind is called multiple times, with this pointing to the first argument in the first call

Log calls bind twice, the first time bind{val: 1}, the second time bind{val: 2}, and the output of this is the context of the first bind

function log() {
    console.log("this".this);
}
console.log(log.bind({ val: 1 }).bind({ val: 2}) ())// { val: 1 }

Copy the code

If arguments are of length 2, the first bind (1) and the second bind (2) will be accepted. If arguments are of length 2, the first bind (1) will be accepted.


function log() {
    console.log("this".this);   // { val: 1 }
    console.log("arguments".arguments);  // {'0': 1, '1': 2}
}

console.log(log.bind({ val: 1 }, 1).bind({ val: 2 }, 2) ())/ / 1
Copy the code

String interceptionsubstr.substring

String.prototype.substr

Returns the number of characters in a string starting at the specified position

Syntax: the second argument, which is the length of the cut

str.substr(start[, length])

String.prototype.substring

Returns a subset of a string from the start index to the end index, or from the start index to the end of the string.

Syntax: second argument, end index

str.substring(indexStart[, indexEnd])

example

Tip:

  1. When neither parameter is set, the effect is the same
  2. The first argument is an integer greater than or equal to 0. The effect is the same if the second argument is not set
const str = "We're all good kids.";

console.log(str.substr())  // We are all good boys
console.log(str.substring()) // We are all good boys

console.log(str.substr(1))  // We are good boys
console.log(str.substring(1)) // We are good boys

console.log(str.substr(-1))  / / child
console.log(str.substring(-1)) // We are all good boys

console.log(str.substr(1.2))  / / have
console.log(str.substring(1.2))  / / the
Copy the code

conclusion

  1. Substr The second argument is the length to intercept
  2. Substring The second argument is the end index
  3. The effect is the same if no argument is specified or the first argument is an integer greater than or equal to 0
  4. If the first argument is negative or the second argument is negative, the processing rules are invalid

See substr and substring for details

traversefor of.for in

for in

Gets the attribute key for Enumerable :true

for of

Iterate over attribute values. Enumerable is not restricted.

example

  1. Added methods to the array prototypegogo.for inIn the result, andfor ofThe result did not appear.
  2. Defines that attribute 2 cannot be traversed,for inIt doesn’t appear in the results, andfor ofIt appears in the result.
// Add methods to the prototype
Array.prototype.gogo = function(){
    console.log("gogo");
}

var a = [1.2.3];

// The key value 2 cannot be enumerated
Object.defineProperty(a, 2, {
    enumerable: false
});
Object.defineProperty(a, "2", {
    enumerable: false
});

for(let p in a){
    // The index is traversed as a string
    console.log(p, typeof p); // 0 string; 1 string; gogo string
}

console.log("-")

for(let v of a){
    console.log(v);  / / 1 2 3
}
Copy the code

conclusion

for in

  1. Gets the attribute key for Enumerable :true.
  2. You can iterate over objects.
  3. You can get the property key on the stereotype.
  4. The numeric property key is traversed as a string. For example, index values

The for of:

  1. Iterate over attribute values. Enumerable is not restricted.
  2. Traversable groups of numbers. In general, objects cannot be traversed. If Symbol. Iterator is implemented, it can be traversed. Such as Array, Map, Set, String, TypedArray, Arguments, and so on
  3. Cannot get the value on the prototype

The current timeDate.now().Performance.now()

Date.now()

Method returns the number of milliseconds since 00:00:00 (UTC), January 1, 1970, to the current time.

Performance.now

Gets the value of the current timestamp (the time elapsed since the context was created), which is a DOMHighResTimeStamp accurate to the millisecond.

<! DOCTYPE html><html lang="en">

<head>
    <script>
        console.log("p1", performance.now())
    </script>
</head>

<body>

    <script>
        console.log("p2", performance.now());

        setTimeout(() = > {
            console.log("p3", performance.now());
        }, 1000)
    </script>
</body>

</html>
Copy the code

conclusion

  1. Date.now()The benchmark is1970 年 1 月 1 日 00:00:00 (UTC)And thePerformance.nowIs context creation.
  2. Date.now()It returns an integer,Performance.nowReturns type double
  3. In theory,Performance.nowHigher precision

Domain informationhost.hostname

location.host

It contains: the host name, followed by a ‘:’ if the URL port number is non-empty, and finally the URL port number

location.hostname

Returns the domain name

example

The default port number for HTTPS and HTTP is not included by host

The host https://developer.mozilla.org:443 is developer.mozilla.org, because the default port of 443 is HTTPS.

      var anchor = document.createElement("a");

      anchor.href = "https://developer.mozilla.org:443/en-US/Location.host";      
      console.log(anchor.host == "developer.mozilla.org:443") // false
      console.log(anchor.host == "developer.mozilla.org") // true

      console.log(anchor.hostname == "developer.mozilla.org:443"); // false
      console.log(anchor.hostname == "developer.mozilla.org");  // true

      anchor.href = "https://developer.mozilla.org:4097/en-US/Location.host";
      console.log(anchor.host == "developer.mozilla.org:4097")  // true
      console.log(anchor.hostname == "developer.mozilla.org")  // true
Copy the code

conclusion

  1. By default, host is equal to hostname
  2. Host Contains an additional port number

Event registrationon.addEventListener

Inline event

Register events.

EventTarget.addEventListener

Method registers the specified listener with an EventTarget, and when the object fires the specified event, the specified callback function is executed.

example

Register the onclick and click events twice, with onclick output once and click output twice.

   <button id="btn" >Am I</button>

    <script>

        const btnEl = document.getElementById("btn");

        btnEl.onclick = () = > console.log("onclick".1);
        btnEl.onclick = () = > console.log("onclick".1);

        btnEl.addEventListener("click".() = > console.log("click".1));
        btnEl.addEventListener("click".() = > console.log("click".2));

    </script>
Copy the code

conclusion

  1. Inline events are overridden and only event bubbling can be used. AddEventListener supports multiple event handlers and supports event capture.

  2. Inline events can be replicated by Node.clonenode in certain cases, not by addEventListener for more details see Node.clonenode

  3. AddEventListener is bound to DOM2 level events and onClick is bound to DOM0 level events

The key timekeypress.keydown

keypress

A key event is fired when the key that produces a character value is pressed. Examples of keys that produce character values are letter keys, number keys, and punctuation keys. Examples of keys that do not produce character values are modify keys such as Alt, Shift, Ctrl, or Meta.

This feature is no longer recommended. Although some browsers may still support it, it may have been removed from the relevant Web standards

keydown

Unlike the KeyPress event, all keys emit the KeyDown event whether or not a character value is generated.

example

Enter 123. The value of keyDown is the same as that of keypress, keyCode

conclusion

  1. Trigger sequence: keyDown -> KeyPress
  2. Keydown: triggered when the user presses any key on the keyboard.
  3. Keypress: triggered when a user presses a character key on the keyboard; The support for Chinese input method is not good, cannot respond to Chinese input
  4. The keyCode of keypress is not very consistent with keyDown;

Asynchronous Loading scriptdefer.async

defer

Asynchronous loading, in which scripts are executed in the order in which they are loaded

async

Load asynchronously and execute scripts out of order.

This picture is worth a thousand words

example

Four script tags, two async, and two defer. The code is as follows:

  • Async1:console.log("async1");
  • Async2:console.log("async2");
  • Defer1:console.log("defer1");
  • Defer2:console.log("defer2");
    <script src="./async1.js" async ></script>
    <div>
        sdfsdfsdfsdfsdfsdfd
    </div>
    <script src="./async2.js" async ></script>

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

As you can see from the above, async2 will sometimes outprint async1, and defer’s output will probably outprint async as well. But the output of Defer must be DEFER1 and then defer2

conclusion

  1. Both loads asynchronously, as defer executes in the load order and async executes out of order

JS Magic: the difference between the innerHTML, innerText, textContent, and value properties keyDown,keypress,keyup when played