Deep understanding of JavaScript function parameters and closure _javascript techniques

Source: Internet
Author: User
Tags anonymous closure closure definition

The most recent learning JavaScript function, the function is a first-class object of JavaScript, want to learn JavaScript, you must have a deep understanding of the function. I put the process of learning into an article, one is to deepen their understanding of the function, the second is to provide readers with learning ways to avoid detours. The content is somewhat many, but all is the author to the function summary.

1. Function parameters

1.1: What is the parameter

1.2: Omission of the parameter

1.3: Parameter Default value

1.4: Parameter Transfer mode

1.5: Parameter with the same name

1.6:arguments objects

2. Closure of the package

2.1: Closure definition

2.2: function expression called immediately (Iife, Immediately invoked function expression)

1. Function parameters

1.1: What is the parameter

When defining a function, it is sometimes necessary to pass extra data to the function, and different external data will have different results, which are called parameters.

 Function Keith (a) {return
 a+a;
 }
 Console.log (Keith (3)); 6

In the code above, the Keith function is passed a parameter a, and the A+A expression is returned.

1.2: Omission of the parameter

Function arguments are not required, and the JavaScript specification allows you to omit the actual arguments that are passed when the call is invoked.

 Function Keith (A, B, c) {return
 A;
 }
 Console.log (Keith (1, 2, 3)); 1
 Console.log (Keith (1));//1
 Console.log (Keith ());//' undefined '

In the code above, the Keith function defines three parameters, but JavaScript does not complain, no matter how many arguments are passed at the time of the call. The default value of the omitted parameter becomes undefined. Knowing both function definitions and function scopes knows that the length property of a function returns the number of arguments. It should be noted that the length property is independent of the number of actual arguments, but only the number of formal arguments returned.

(actual parameter: An argument that is passed when invoked. Formal parameters: Parameters that are passed when the definition is defined. )

However, there is no way to omit the elements that are only on the front, but to retain the elements. If you must omit the front element, only the incoming undefined is displayed.

 Function Keith (A, b) {return
 A;
 }
 Console.log (Keith (, 1)); syntaxerror:expected expression, got ', '
 console.log (Keith (Undefined, 2));//' undefined '

In the code above, if the first argument is omitted, the browser will make an error. If you pass undefined to the first parameter, there is no error.

1.3: Default Value

In JavaScript, the default value for a function parameter is undefined. However, it is useful to set different default values in some cases. The general policy is to give a value if the principal test parameter value is undefined, or, if not, return the value passed by the actual parameter.

 Function Keith (A, B) {
 (typeof b!== ' undefined ')? b = b:b = 1;
 return a * b;
 }
 Console.log (Keith (15));
 Console.log (Keith (15, 2))//30

In the code above, a judgment is made. When the B parameter is not passed in at the time of the call, the default is 1.

Starting with ECMAScript 6, the default parameter is defined (parameters). Using default parameters, the check in the function body is no longer needed.

 Function Keith (A, B = 1) {return
 a * b;
 }
 Console.log (Keith (15));
 Console.log (Keith (15, 2))//30

1.4: Parameter Transfer mode

There are two ways to transfer the function parameters, one is the transfer of value and the other is the transmission of the address.

When the function argument is the original data type (string, numeric, Boolean), the parameter is passed as a pass value. That is, modifying parameter values in a function body does not affect the outside of the function.

 var a = 1;
 function Keith (num) {
 num = 5;
 }
 Keith (a);
 Console.log (a); 1

In the code above, global variable A is a value of the original type, and the way to pass the function Keith is to transfer the value. Therefore, within a function, the value of a is a copy of the original value, no matter how it is modified, does not affect the original value.

However, if the function argument is a value (array, object, other function) of a compound type, the pass is passed by reference. That is, the address of the original value is passed in to the function, so modifying the parameter inside the function will affect the original value.

 var arr = [2, 5];
 Function Keith (ARR) {
 arr[0] = 3;
 }
 Keith (arr);
 Console.log (Arr[0]); 3

In the code above, the incoming function, Keith, is the address of the Parameter object arr. Therefore, modifying the ARR first value inside a function affects the original value.

Note that if the function is modified internally, instead of an attribute of the parameter object, instead of replacing the entire argument, the original value will not be affected.

 var arr = [2, 3, 5];
 Function Keith (ARR) {
 ARR = [1, 2, 3];
 }
 Keith (arr);
 Console.log (arr); [2,3,5]

In the code above, within the function Keith, the parameter object arr is replaced by the whole with another value. The original value is not affected at this time. This is because the formal parameter (ARR) has an assignment relationship with the actual parameter Arr.

1.5: Parameter with the same name

If there is a parameter with the same name, the value that appears in the last face is changed to undefined if the value of the last argument is not supplied.

 Function Keith (A, a) {return
 A;
 }
 Console.log (Keith (1, 3)); 3
 Console.log (Keith (1));//undefined

If you want to access the first argument in a parameter with the same name, use the arguments object.

 Function Keith (A, a) {return
 arguments[0];
 }
 Console.log (Keith (2)); 2

1.6 Arguments Object

A special variable arguments can be accessed within each function in JavaScript. This variable maintains all the list of arguments passed into this function.

The arguments object contains all the parameters of the function runtime, Arguments[0] is the first argument, Arguments[1] is the second argument, and so on. This object can be used only within the function body.

You can access the length property of the arguments object to determine exactly how many arguments to take when the function is called.

 Function Keith (A, B, c) {
 console.log (arguments[0]);//1
 Console.log (arguments[2);//3
 Console.log ( Arguments.length); 4
 }
 Keith (1, 2, 3, 4);

Arguments the relationship between an object and an array

The arguments object is not a single array (array). Although it has an array-related attribute length in syntax, it does not inherit from Array.prototype, but it is actually an array object of the class. Therefore, you cannot use standard array methods for arguments variables, such as push, pop, or slice. However, you can use the Length property in the array.

You typically convert a arguments object to an array using the following methods.

var arr = Array.prototype.slice.call(arguments);

2. Closure of the package

2.1: Closure definition

To understand closures, you need to first understand the difference between global scope and local scope. Within a function, global variables defined under global scope can be accessed, but outside the function there is no access to local variables defined within the function (local scope).

var a = 1;
Function Keith () {return
 A;
 var b = 2;
 }
 Console.log (Keith ()); 1
 console.log (b);//referenceerror:b is not defined

In the code above, global variable A can be accessed within the function Keith. However, local variable B cannot be accessed outside of the function.

If you need to get a local variable inside a function, you can define a function only by defining it inside the function.

 Function Keith () {
 var a=1;
 function Rascal () {return
 A;
 }
 return rascal;
 }
 var result=keith ();
 Console.log (Result ()); 1
 function Keith () {
 var a=1;
 return function () {return
 A;}
 ;
 }
 var result=keith ();
 Console.log (Result ())//1

In the code above, the two methods are the same, and the only difference is whether the internal function is an anonymous function. Function rascal is inside the function Keith, when all local variables within Keith are visible to rascal. But the converse is not, and the local variables inside the rascal are invisible to Keith. This is the "chain scoped" structure (chain scope) peculiar to the JavaScript language, where child objects look up the variables of all the parent objects at one level. Therefore, all the variables of the parent object are visible to the child, and the opposite is not true. The return value of the function, Keith, is the function rascal, because Rascal can read Keith's internal variables, so we can get Keith's internal variables externally.

A closure is a function rascal, that is, a function that can read the variables inside other functions. Because in a JavaScript language, only a child function inside a function can read internal variables, the closure can be simply understood as "functions defined within a function." The biggest feature of closures is that it can "remember" the environment in which it was born, such as Rascal remembered the environment in which it was born, so Keith's internal variables can be obtained from rascal.

Closures make it possible for the environment to be born. Take a look at the following example, the closure allows the internal variable to remember the result of the operation on the last call.

 function Keith (num) {return
 function () {return
 num++;}
 ;
 }
 var result = Keith (2);
 Console.log (Result ())//2 Console.log (Result ())
 //3 Console.log (Result ())
 //4

In the code above, the argument num is actually equivalent to the local variables defined within Keith. With closures, the status of NUM is preserved, and each call is evaluated on the basis of the last call. As you can see, closure result makes the internal environment of the function Keith always exist.

Through the above examples, summed up the closure of the characteristics:

1: Define another function inside a function, and return internal functions or immediately execute internal functions.

2: The internal function can read the local variables defined by the external function

3: Keep local variables in memory always. In other words, closures make it possible for the environment to be born.

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

 function Keith (name) {
 var age;
 function Setage (n) {age
 = n;
 }
 function Getage () {return age
 ;
 }
 return {
 name:name,
 setage:setage,
 getage:getage
 };
 }
 var person = Keith (' Keith ');
 Person.setage ();
 Console.log (Person.name); ' Keith '
 Console.log (Person.getage ());//21

2.2: Call-now function expression (iife)

In general, this "executed function expression" is used only for anonymous functions. Its purpose is two: first, it is not necessary to name the function, avoid polluting the global variable; the second is that the Iife internally forms a separate scope that encapsulates some private variables that cannot be read externally.

Closures in loops

A common error occurs in loops using closures, assuming we need to call the loop ordinal in each loop

 for (Var i=0;i<10;i++) {
 settimeout (function () {
 console.log (i);//10
 }, 1000)
 }

The code above does not conform to our expectations, the output number is 0-9. But it will output the number 100 times.

When an anonymous function is invoked, the anonymous function maintains a reference to the global variable I, which means that the result of the I loop is remembered. At this point the for loop ends and I's value is modified to 10.

To get the desired effect and avoid referencing errors, we should use Iife to create a copy of the global variable I in each loop.

for (var i = 0; i < i++) {
 (function (e) {
 settimeout (function () {
 console.log (e);//1,2,3,...., 10
   
    }, 1000);
 } (i);
 }
   

The external anonymous function executes immediately and takes I as its parameter, at which point the e variable in the function has a copy of I. When an anonymous function passed to SetTimeout executes, it has a reference to E, which is not changed by the loop.

Above is the entire content of this article, I hope the content of this article for everyone's study or work can bring some help, but also hope that a lot of support cloud Habitat community!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.