Focus on

More front-end knowledge invites the front-end enthusiasts to join the front-end technology exchange community, the community is mainly to share the technology stack, personal experience, technical exchanges, questions and other front-end system exchanges

Click on the text below to join

Front-end bigwig technology exchange community

1. Function definition and invocation

1.1 Definition of functions

  1. Function Keyword (named function)

    function f1() {
        console.log('Named function')}Copy the code
  2. Mode 2 Function expression (anonymous function)

    var f2 = function () {
        console.log('Anonymous function')}Copy the code
  3. Mode 3 New Function()

    /* Parameter 1: function parameter 2: function parameter 3: function body */
    var f3 = new Function('m'.'n'.'console.log(m-n)')
    // Pass in arguments
    f3(4.2)
    
    Copy the code

Pay attention to

  • All arguments in Function must be strings
  • The third method is less efficient to implement and is not easy to write, so it is less used

1.2 Function Invocation

 // Normal functions: named functions and anonymous functions
function f1() {
    console.log('Where do men meet but once?');
}
var f2 = function () {
    console.log('Cold river lonely shadow, river's lake old friend, meet why ever met');
}
// Functions in objects, technically called methods, pass through objects. Method call
var Person = {
    speak: function () {
        console.log('Life is full of songs'); }}// Constructor: called with the new keyword
function Star() {}new Star()
// The event handler is called when the event is triggered
element.onclick = function () {}// The timer function is called by the timer to select the time
setInterval(function () {},1000)
// Execute the function immediately: call it immediately
(function () {
    console.log('first off')
}())
Copy the code

2.this

2.1 The this pointer inside the function

These “this” references are determined when we call the function. Depending on how this is called, the direction of this is different

Generally pointing to our caller.

2.2 Change the this pointer inside the function

2.2.1 call method

The call() method calls an object. This is simply the way a function is called, but it can change the this direction of the function

Application scenario: Often perform inheritance.

var o = {
	name: 'andy'
}
 function fn(a, b) {
      console.log(this);
      console.log(a+b)
};
fn(1.2)// This refers to window and the result is 3
fn.call(o,1.2)// This refers to the object o, separated by a comma, and the result is 3
Copy the code

The above code runs as follows:

Review implementation inheritance using this

2.2.2 the apply method

The use of the apply method is very similar to that of call, except that arguments cannot be passed as a list of arguments; they must be passed as an array

var o = { name: 'andy' } function fn(a, b) { console.log(this); console.log(a + b) }; Fn.call (o, 1,2) // apply(o, 1,2); fn.apply(o, 1,2);Copy the code

As you can see, we pass in an array of arguments to the function, but the function is automatically expanded to a list of arguments

Using this feature, we can combine the math.max method to find the maximum or minimum value of an array

The math.max method maximizes a set of numbers in the following syntax

Math. Max (1, 2, 3, 4, 5)Copy the code

Parameters are in the format of a parameter list

Arrays can be passed in using Apply

var numbers = [3, 2, 44, 11, 66, 7]
var max=Math.max.apply(null,numbers)
console.log(max);
Copy the code

You can also use the Spread syntax of ES6

var max=Math.max(... numbers)Copy the code

2.2.3 the bind method

Developer.mozilla.org/zh-CN/docs/…

The bind() method does not call the function, but can change the this reference inside the function

You can use bind if you just want to change this and don’t want to call the function

Application scenario: Do not call the function, but still want to change the this reference

 var o = {
 name: 'andy'
 };

function fn(a, b) {
	console.log(this);
	console.log(a + b);
};
var f = fn.bind(o, 1.2); // f is the new function returned by bind
f();// Call the new function this to the object O separated by commas
Copy the code

To reassure

The code above

var f = fn.bind(o, 1, 2)
Copy the code

The function f is the same as the function f, but the internal reference of this is different

The following code is called to execute function f, and the above code only does the above task, but does not execute function fn and does not execute new function f

f()
Copy the code

application

There is a div on the page, which is red by default. After the mouse hover, it turns blue, and after 3 seconds, it returns to red

var div = document.querySelector('div')
div.addEventListener('mouseover', function () {
    this.style.backgroundColor = 'blue'
    setTimeout(function () {
    	div.style.backgroundColor = 'red'
    }, 3000);
})
Copy the code

In the timer, this=window, so you cannot use this, you must use the element name div

Of course you can use var that=this

However, both approaches have problems, such as achieving the following effect

There are three divs on the current page, all of which are red by default. Hover over one of them and the color changes to blue. After 3 seconds, the color changes to red

var divs = document.querySelectorAll('div') for (var i = 0; i < divs.length; i++) { divs[i].addEventListener('mouseover', Function () {/ / here this = current triggers a specific div enclosing style. The backgroundColor = 'blue' setTimeout (function () {/ / the code below should be how to write}, 3000); })}Copy the code

This =window in timer, so window cannot be used

You cannot use divs[I] either, because the index of I is not what you would expect at the time of the event

Of course you can use that=this, but you will create more local variables

You can use the bind method

Bind works best here, because you just change the reference to this in the function, and it doesn’t happen right away. It’s called again 3 seconds later

Note: The bind method creates a new function, so 3 seconds later it calls the new function, in which this=div

Ask? Don’t you need to declare a variable to receive the new function created by BIND? Why not here?

Students, please be clear: when do I need a return value, and when do I not

2.2.4 Similarities and differences of call, apply and bind

  • Common: Both can change the “this” direction

  • Difference:

    • Call and Apply call the function and change the this reference inside the function.
    • Call and Apply pass different parameters, which are separated by commas, and apply pass in arrays
    • Bind does not call a function; it can change the this pointer inside a function.
  • Application scenarios

    1. Call often does inheritance.
    2. Apply is often associated with arrays. For example, using mathematical objects to realize the maximum and minimum values of arrays
    3. Bind does not call the function, but also wants to change the this pointer. For example, change the this pointer inside the timer.

3. Strict mode

3.1 What is strict mode

JavaScript provides strict mode in addition to normal mode. ES5’s strict mode is a way to adopt restrictive JavaScript variants, that is, to run JS code under strict conditions.

Strict mode is only supported in IE10 or later, and is ignored in older browsers.

Strict mode makes some changes to normal JavaScript semantics:

1. Eliminate some unreasonable and unrigorous aspects of Javascript syntax and reduce some weird behaviors.

2. Eliminate some unsafe parts of code operation to ensure the safety of code operation.

3. Improve the efficiency of the compiler and increase the running speed.

4. Disable some syntax that might be defined in future versions of ECMAScript, paving the way for future versions of Javascript. For example, reserved words such as class,enum,export, extends, import, and super cannot be variable names

Talk about TS

3.2 Enabling the Strict Mode

Strict patterns can be applied to entire scripts or to individual functions. Therefore, in use, we can divide strict mode into strict mode for scripts and strict mode for functions.

  • The script turns on strict mode
  • Function to turn on strict mode
 <script>
        // Enable strict mode in the current script: effect between script start and end tags
        // 'use strict'
        var name='yhb'
        age=20
        function fn(){
            // Enable strict mode in function
            'use strict'
            gender='male'
        }
        fn()
    </script>
Copy the code

3.3 Changes in strict mode

Developer.mozilla.org/zh-CN/docs/…

Strict mode makes some changes to the syntax and behavior of Javascript.

'use strict'
num = 10 
console.log(num)// Use undeclared variables after strict schema
--------------------------------------------------------------------------------
var num2 = 1;
delete num2;// Strict mode does not allow variables to be deleted: Variables are deleted to free memory, usually by setting the value of the variable to NULL
--------------------------------------------------------------------------------
function fn() {
 console.log(this); // This is undefined in the global scope function in strict mode
}
fn();  
--------------------------------------------------------------------------------- function Star() {
    this.gender = 'male';
}
// Call Star without new, this=undefined
console.log(Star().gender)
// Add new to call Star, this= object
console.log(new Star().gender)
----------------------------------------------------------------------------------
setTimeout(function() {
  console.log(this); // In strict mode, timer this still points to window
}, 2000);  
Copy the code

In addition, the parameter names of functions in strict mode should be unique

Function f1(m, m) {console.log(m + m)} f1(1,2) function f1(m, m) {console.log(m + m)} f1(1,2Copy the code

In strict mode, an error is reported

4. Higher-order functions

Higher-order functions are functions that operate on other functions, taking functions as arguments or output functions as return values.

Function as argument:

Function as the return value

A function is also a data type that can also be passed as an argument to another argument. The most typical is as a callback function.

A function can also be passed back as a return value

Function as argument case:

Function fn(m, n, callback) {console.log(m + n)} fn(3, 4, 4) {console.log(m + n) {console.log(m + n)} Function () {console.log(' I am the callback ')})Copy the code

Jquery makes a lot of use of callback functions, such as performing an action after an animation

5. The closure

5.1 Review of scope of variables

Variables can be divided into two types depending on their scope: global variables and local variables.

  1. Global variables can be used inside functions.
  2. Local variables may not be used outside functions.
  3. Local variables in this scope are destroyed when the function completes execution.

5.2 What is a Closure

Developer.mozilla.org/zh-CN/docs/…

In JS, each time a function is created, a closure is generated that contains the function and its lexical environment (presumably similar to the execution context).

Closures are an execution mechanism: an inner function can always access variables and arguments declared in its outer function, even after its outer function has finished executing

/* Nested functions in a function are fine in JS. 1) internal scope can access external scope, so f2 can access variables in f1. 2) global scope, Function f1() {var m = 100 return function() {console.log(m)}} var myfunc=f1() Myfunc () executes f2() myfunc() // f2() // console.log(m)Copy the code

The above example shows that closures extend the scope of variables.

To reassure

In general, after the following code is executed, the external function f1 completes, and the internal member data of the function is destroyed, including the variable m, but since the internal function F2 uses the variable M, and the function F2 is returned to the variable myfunc, the variable myfuc refers to the internal function F2

F2 has not been executed, so the external function f1 cannot release its own variable m

 f1()
Copy the code

We can call the subfunction F2 a closure (debatable)

When a function is created, it forms a closure that gives the inner function access to the variables and arguments of the outer function, and makes the data inside the function accessible outside the function by returning the inner function outward

Three features of closures

1) Function nested function

2) Inside a function, you can access variables and arguments outside the function

3) After the execution of external functions, parameters and variables will not be collected by the garbage collection mechanism

5.3 Closure case

  1. Use closure to get the current li index
for (var i = 0; i < lis.length; Function (I) {lis[I].onclick = function() {if (lis[I].onclick = function() {if (lis[I].onclick = function() { console.log(i); } })(i); }Copy the code

However, using closures in this case is not the best solution because each loop creates a function, and each value of I is saved and cannot be released, so execution is inefficient

It is preferable to store the value of I in a custom attribute of the Li tag

Code (Task list)

  1. Closure application – After 3 seconds, print the contents of all li elements

The following code iterates through all the LI tags, creating three timers that print the contents of each LI tag element after 3 seconds

 for (var i = 0; i < lis.length; i++) {
   (function(i) {
     setTimeout(function() {
     console.log(lis[i].innerHTML);
     }, 3000)
   })(i);
}
Copy the code

In fact, it is possible to use the bind method we learned earlier

Code (Task list)

  1. Closure application – Calculate taxi fares
/* Demand analysis Taxi fare starts at 13(within 3 kilometers) and increases by 5 yuan for each additional kilometer. Var car = (function () {var start_price = 13 var start_juli = 3 var total = 0 return { price: function (juli) { if (juli <= start_juli) { total = start_price } else if (juli > 3) { total = start_price + (juli - start_juli) * 5 } return total }, yondu: function (flag) { return flag ? total + 2 : total } } })() console.log(car.price(3)); console.log(car.price(10)); console.log(car.yondu(false)); console.log(car.yondu(true));Copy the code

To reassure

The code in a function executes immediately and does not wait to be called, so the variable CAR refers to an object

2. The referenced object contains two functions, price and YONGdu, which are children of the immediate function

3. Closures are formed because variables in external functions are referenced in subfunctions

4. The above example does not have to be written this way, just to practice using closures

6. Recursion

6.1 What is recursion

** Recursion: ** A function is recursive if it can call itself internally. Simple to understand: a function that calls itself internally is a recursive function

** Note: recursive functions function as loop effect, because recursion is prone to “stack overflow” error, so must add exit condition return.

6.2 Use recursion to find the factorial of 1~n

1 * 2 * 3 * 4 *... n
 function fn(n) {
     if (n == 1) { // End condition
       return 1;
     }
     return n * fn(n - 1);
 }
 console.log(fn(3));
Copy the code

6.3 Using recursion to find Fibonacci sequence

// Fibonacci sequence 1, 1, 2, 3, 5, 8, 13, 21...
// The user can input a number n to find the corresponding rabbit sequence value
// We only need to know the first two terms of the user input n (n-1 n-2) to calculate the corresponding sequence value of n
function fb(n) {
  if (n === 1 || n === 2) {
        return 1;
  }
  return fb(n - 1) + fb(n - 2);
}
console.log(fb(3));
Copy the code

6.4 Traverse data by recursion

// We want to make a data object that can be returned by typing an ID number
 var data = [{
   id: 1.name: 'goods'.goods: [{
     id: 11.gname: 'the refrigerator.goods: [{
       id: 111.gname: '海尔'
     }, {
       id: 112.gname: 'beauty']}, {},id: 12.gname: 'Washing machine'}]}, {id: 2.name: 'dress'
}];
//1. Use forEach to iterate through each object
 function getID(json, id) {
   var o = {};
   json.forEach(function(item) {
     // console.log(item); // 2 array elements
     if (item.id == id) {
       // console.log(item);
       o = item;
       return o;
       // 2. We want to get the data of the inner layer
       // There should be an array of goods and the array length is not zero
     } else if (item.goods && item.goods.length > 0) { o = getID(item.goods, id); }});return o;
}
Copy the code

Focus on

More front-end knowledge invites the front-end enthusiasts to join the front-end technology exchange community, the community is mainly to share the technology stack, personal experience, technical exchanges, questions and other front-end system exchanges

Click on the text below to join

Front-end bigwig technology exchange community