Implement a sleep function



= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =



If the property is inheritedIs traversable, then it will befor... inLoop through to. However, in general, you want to iterate over the properties of the object itself, so usefor... in“Should be used in combinationhasOwnPropertyMethod to determine whether an attribute is a property of the object itself.



= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Closures are a feature of the Javascript language, and many advanced applications rely on them.

To understand closures, you must first understand variable scope. As mentioned earlier, JavaScript has two types of scope: global scope and function scope. Global variables can be read directly from within a function.



In the above code, function f1 can read the global variable n.

However, variables declared inside the function cannot be read outside the function.



In the above code, the variable n declared inside function f1 is unreadable outside the function.

If, for any number of reasons, you need to get local variables inside the function. Normally, this is not possible and can only be achieved through workarounds. That is to define another function inside the function.



In the above code, function f2 is inside function f1, and all local variables inside f1 are visible to F2. But the reverse is not true. Local variables inside F2 are invisible to F1. This is the JavaScript language’s unique “chain scope” structure, where a child object finds all the variables of its parent object one level up. So, all variables of the parent object are visible to the child object, and not the other way around.

Since f2 can read local variables of F1, we can read its internal variables outside f1 simply by returning f2.



In the above code, the return value of function f1 is function f2, and since f2 can read the internal variables of f1, it can get the internal variables of F1 from the outside.

The closure is function F2, which is a function that can read the internal variables of other functions. Because in JavaScript, only subfunctions inside a function can read internal variables, you can simply think of closures as “functions defined inside a function.” The most important feature of closures is that they can “remember” the environment in which they were born. For example, F2 remembers the environment in which it was born, F1, so that the internal variables of F1 can be obtained from F2. In essence, a closure is a bridge between the inside of a function and the outside.

Closures are useful in two ways: they can read variables inside a function, and they can keep those variables in memory. In other words, closures can keep the environment in which they were created. In the following example, a closure causes an internal variable to remember the result of the operation last called.



In the above code, start is an internal variable to the function createIncrementor. With closures, the state of start is preserved, and each call is evaluated on the basis of the last. As you can see, the inc closure makes the internal environment of createIncrementor always exist. So, a closure can be thought of as an interface within the scope of a function.

Why is that? The reason for this is that the INC is always in memory, and its existence is dependent on createIncrementor, so it is always in memory and will not be collected by the garbage collection mechanism after the call is completed.

Another use of closures is to encapsulate the private properties and methods of an object.



In the above code, the internal variable _age of the function Person, through closures getAge and setAge, becomes a private variable that returns object P1.

Note that each time the outer function runs, a new closure is generated, which in turn preserves the inner variables of the outer function, so memory consumption is high. Therefore, closures should not be abused, or they can cause performance problems for your web page.

Summary of what closures do

1. The lexical scope in which the function definition is accessible (preventing it from being reclaimed).

2. Privatization variables



3. Simulate block-level scope



4. Create modules



The module mode has two prerequisites (from JavaScript You Don’t Know)

  • There must be an external enclosing function, which must be called at least once (each call creates a new module instance)
  • The enclosing function must return at least one inner function so that the inner function can form a closure in the private scope and can access or modify the private state.

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Typical “array-like objects” are the Arguments object for a function, as well as most DOM element sets, and strings.



The above code contains three examples, none of which are arrays (the instanceof operator returns false), but all look very much like arrays.

The slice method of an array turns an “array-like object” into a real array.

var arr = Array.prototype.slice.call(arrayLike);Copy the code

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Avoid this in array handling methods

The map and foreach methods of an array allow you to supply a function as an argument. This should not be used inside this function.



In the preceding code, this in the callback to the foreach method refers to the window object, and therefore does not fetch the value of o.v. The reason for this is the same as for the multiple layers of “this” in the preceding paragraph: the inner layer of “this” does not point to the outer layer, but to the top-level object.

One way to solve this problem, as mentioned earlier, is to fix this with an intermediate variable.



Another way is to take this as the second argument to the foreach method, fixing the environment in which it runs.



= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

JS

1. Basic types (value type or primitive type) : Number, Boolean, String, NULL, Undefined and ES6’s Symbol 2. Reference types: Object, Array, Function, Date, etc

Location in memory

  • Basic type: occupies a fixed space, stored in the stack;

  • Reference type: the size is not fixed, stored in the heap;

A stack is automatically allocated memory space, which is automatically released by the system. With level 1 cache, it is usually in storage when called and is released immediately after the call. Heap, on the other hand, is dynamically allocated memory that is not automatically freed, regardless of size. With level 2 caching, the life cycle is dependent on the GC algorithm of the virtual machine

When a method is executed, each method builds its own stack. Variables defined in the method are placed in the stack one by one. As the method is executed, the stack of the method is destroyed. Therefore, all variables defined in a method are placed in stack memory; The stack stores the base variable and reference variables to some objects. The base variable’s value is stored in the stack, and the reference variable stored in the stack is the address of an array or object in the heap. This is why changing the reference type always affects other reference variables that point to that address.

When we create an object in a program, that object is saved in the run-time data area for reuse (because objects are usually expensive to create), and this run-time data area is the heap memory. Will not end with the method of objects in the heap memory and destruction, even after the method, the object may also be another reference variables referenced (method of parameter passing is common), then the object is not destroyed, only when there is no reference to an object variables refer to it, the system of garbage collection will check the recycling it.

# Assign, shallow copy, deep copy

  • For a value of a primitive type, assignment, shallow copy, and deep copy copy the value of the primitive type to a new variable, and the operations between the two variables do not affect each other.

  • For reference type values,

  • The two variables point to the same address. When one variable changes, the other also changes.

    The shallow copy will result in a new variable, which will not refer to the same variable as the previous one. The change will not change the basic type of the original data, but will change the reference type of the original data

    The result of the deep copy is a new variable whose changes do not affect the metadata

Is it pointing to the same object as the original data The first layer of data is the basic data type The source data contains child objects
The assignment is A change changes the original data with it A change changes the original data with it
Shallow copy no Changes do not change the original data with them A change changes the original data with it
Deep copy no Changes do not change the original data with them Changes do not change the original data with them



# # shallow copy

Common shallow copy methods for arrays include slice,concat, array.from (), and es6’s destructor



The common shallow copy method of Object, object.assign (), is destroyed by ES6



Implement a shallow copy yourself



# # deep copy

A more crude approach is to use json.parse (json.stringify (obj)).



Json.parse (json.stringify (obj)) looks good, but the MDN document description makes it clear:

Undefined, any function, and symbol values are either ignored during serialization (when they occur in non-array object property values) or are converted to NULL (when they occur in arrays).Copy the code

Json.parse (json.stringify (obj)) has several drawbacks:

  1. Object whose property value is a function cannot be copied.
  2. Properties on the prototype chain cannot be copied
  3. Data of type Date cannot be processed correctly
  4. Cannot handle regexps
  5. Ignore the symbol
  6. Ignores undefined

Json.parse (json.stringify (obj)) satisfies 90% of usage scenarios in normal development. Let’s implement one ourselves



# Parameter passing

All function arguments are passed by value. That is, assigning a value outside a function to an argument inside a function is just like assigning a value from one variable to another;

Basic types of



Reference types



Many people mistakenly think that an object modified in a local scope is reflected in a global scope to indicate that parameters are passed by reference. But the example above shows that if person is passed by reference the final person.name should be Tom. In fact, when obj is overridden internally, the variable refers to a local variable. This variable is destroyed at the end of the function. (This is in the JS advanced programming to see, is not very clear)

# Method of judgment

Use Typeof for basic types and Instanceof for reference types

Note specifically that typeof null is"object", null instanceof Object istrue;Copy the code



Object. The prototype. ToString. Call ([]). Slice (8-1) interested students can take a look at this is stem what ofCopy the code

# summary



= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

# understand json

The link in the SRC attribute of the script tag can access cross-domain JS scripts. With this feature, instead of returning JSON data, the server returns a js code calling a function, which is called in SRC, thus implementing cross-domain. (Not only that, we also found that all tags with the “SRC” attribute have cross-domain capability, such as <\script>, <\img>, <\iframe>)

##JSONP client implementation

Whether it’s jQuery, ExtJS, or any other framework that supports JSONP, the work behind the scenes is the same. Here’s a step-by-step guide to implementing JSONP on the client side:

1. As we know, even if the code in the cross-domain JS file (which conforms to the web script security policy, of course), the Web page can be executed unconditionally.

In the root directory of the remoteserver remoteserver.com, there is a remote. Js file code as follows:

alert('I'm a remote file');Copy the code

There is a jsonp. HTML page on the localserver localserver.com.

<! DOCTYPE html PUBLIC"- / / / / W3C DTD XHTML 1.0 Transitional / / EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>
 
</body>
</html>Copy the code

No doubt, a prompt will pop up indicating that the cross-domain invocation was successful.

2. Now we define a function on the jsonp. HTML page and call it with data passed in to remote.js.

The jsonp. HTML page code is as follows:

<! DOCTYPE html PUBLIC"- / / / / W3C DTD XHTML 1.0 Transitional / / EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('I am a local function that can be called by a cross-domain remote.js file, and the data that remote JS brings is:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>
 
</body>
</html>Copy the code

The code of the remote.js file is as follows:

localHandler({"result":"I'm the data from remote JS."});Copy the code

After running, check the result. The page successfully pops up a prompt window, showing that the local function is successfully invoked by the cross-domain remote JS, and the data brought by the remote JS is also received. I’m glad to see that the purpose of fetching data remotely across domains is basically fulfilled, but another problem arises: how do I tell the remote JS to know the name of the local function it should call? After all, jSONP servers have many service objects that have different local functions. Let’s move on.

3, smart developers, it’s easy to think of, as long as the service side of js scripts are dynamically generated line bai, so that the caller can pass a parameter used to tell the server to “I want a call XXX function of js code, please return to me”, then the server can according to client’s demand to generate the js script and response.

Look at the code for the jsonp. HTML page:

<! DOCTYPE html PUBLIC"- / / / / W3C DTD XHTML 1.0 Transitional / / EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript"Var flightHandler = // return the result of flight information queryfunction(data){
        alert('The result of your flight query is: ticket price' + data.price + ', ' + 'more than ticket' + data.tickets + 'one. '); }; // The url that provides the jSONp service (no matter what type of address, the return value is a javascript code) var url ="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; Var script = document.createElement();'script');
    script.setAttribute('src', url); / / add the script tag to the head, this time the call started document. The getElementsByTagName ('head')[0].appendChild(script); 
    </script>
</head>
<body>
 
</body>
</html>Copy the code

This time the code change is relatively big, no longer directly write remote JS file dead, but code to achieve dynamic query, and this is the core part of the JSONP client implementation, the focus of this example is how to complete the whole process of jSONP call. We see that the url of the call passes a code parameter telling the server that I am looking for information about flight CA1998, and the callback parameter tells the server that my local callback function is called flightHandler, so please pass the query result into this function and call it. OK, the server is smart, this page called flightresult.aspx generates a piece of this code for jsonp.html

(I won’t show you the server implementation here, it doesn’t matter what language you choose, it’s all about concatenating strings) :

flightHandler({
    "code": "CA1998"."price": 1780,
    "tickets": 5});Copy the code

At this point, I believe you can understand the client implementation of JSONP, right? What remains is how to encapsulate the code so that it interacts with the user interface so that it can be invoked multiple times and repeatedly

How does jQuery implement jSONP calls?

<! DOCTYPE html PUBLIC"- / / / / W3C DTD XHTML 1.0 Transitional / / EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"> text/javascript"> jQuery(document).ready(function(){ $.ajax({ type: "get", async: false, url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998", dataType: "jsonp", jsonp: "callback",// the name of the argument passed to the request handler or page to get the name of the jSONp callback function (default :callback).flightHandler",// the name of the custom jSONp callback function, which defaults to a random function name automatically generated by jQuery.?", jQuery will automatically process the data for you success: function(json){alert(' You query the flight information: ticket: '+ json.price +', remaining tickets: '+ json.tickets +'. '); }, error: function(){ alert('fail'); }}); });     Copy the code

Isn’t that a little weird? Why didn’t I write flightHandler this time? And it worked! This is what jQuery is doing with JSONp-type Ajax (although jQuery classifiers JSONp as Ajax, but they are not the same thing). JQuery automatically generates the callback function and pulls the data out for the success property method to call. supplement

Here are some additional notes on the similarities and differences between Ajax and JSONP:

1. Ajax and JSONp both “look” similar in the way they are called and the purpose is to request a URL and then process the data returned by the server, so frameworks like jquery and Ext encapsulate JSONP as a form of Ajax.

2. But Ajax and JSONP are fundamentally different things. The core of Ajax is getting non-page content through XmlHttpRequest, while the core of JSONP is dynamic addition

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

Implement array deduplicating

uniq([1, 2, 3, 5, 3, 2]); // [1, 2, 3, 5]

1. Add the data type Set using ES6

function uniq(arry) {
    return [...new Set(arry)];
}Copy the code

2. Use indexOf

function uniq(arry) {
    var result = [];
    for(var i = 0; i < arry.length, i++){
        if(result.indexOf(arry[i]) === -1){ result.push(arry[i]); }}return result;
}Copy the code

3. Use includes

function uniq(arry) {
    var result = [];
    for(var i = 0; i < arry.length, i++){
        if(!result.includes(arry[i])){
            result.push(arry[i]);
        }
    }
    return result;
}Copy the code

4. Use reduce

function uniq(arry){
    return arry.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], [])
}Copy the code

5. Use Map

function uniq(arry){
    let map = new Map();
    let result = new Array();
    for(let i - 0; i < arry.length; i++){
        if(map.has(arry[i])){
            map.set(arry[i], true);
        }else {
            map.set(arry[i], false); result.push(arry[i]); }}return result;
}Copy the code

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

You will soon get something you have always desired.