Functions of JavaScript Shaoguan

Source: Internet
Author: User
Tags array sort
A function is a piece of code that is defined only once, but can be executed or called any time. In JavaScript, functions are objects and programs can manipulate them at will. For example, you can assign a function to a variable, pass it as a parameter to other functions, Set Properties for them, or even call their methods. If a function is attached to an object as an attribute of the object, it is called the object method. A function is a piece of code that is defined only once, but can be executed or called any time. In JavaScript, functions are objects and programs can manipulate them at will. For example, you can assign a function to a variable, pass it as a parameter to other functions, Set Properties for them, or even call their methods. If a function is attached to an object as an attribute of the object, it is called the object method. If a function is nested in another function, it can access any variables in the scope where they are defined.

Function Definition

In JavaScript, a Function is actually an object. Every Function is an instance of a Function constructor. Therefore, a Function name is actually a pointer to a Function object and will not be bound to a Function. Functions are usually defined in the following three methods. For example:

// Write Method 1: function declaration (recommended) function sum (num1, num2) {return num1 + num2;} // write Method 2: function expression (recommended) var sum = function (num1, num2) {return num1 + num2 ;}; // method 3: Function Constructor (not recommended) var sum = new Function ("num1 ", "num2", "return num1 + num2 ");

Since the function name is only a pointer to the function, the function name is no different from other variables that contain the object pointer. In other words, a function may have multiple names. For example:

function sum(num1, num2){     return num1 + num2; } console.log(sum(10,10));        // 20  var anotherSum = sum; console.log(anotherSum(10,10)); // 20  sum = null; console.log(anotherSum(10,10)); // 20

No overload

Imagining a function name as a pointer also helps you understand why JavaScript does not have the concept of function overloading.

function addSomeNumber(num){     return num + 100; }  function addSomeNumber(num) {     return num + 200; }  var result = addSomeNumber(100);    // 300

Obviously, two functions with the same name are declared in this example, and the result is that the subsequent functions overwrite the previous functions. The above code is actually no different from the following code.

var addSomeNumber = function (num){     return num + 100; };  addSomeNumber = function (num) {     return num + 200; };  var result = addSomeNumber(100);    // 300

After rewriting the code, you can easily understand that when creating a second function, it actually overwrites the variable addSomeNumber that references the first function.

Function declaration and Expression

When the parser loads data to the execution environment, it does not treat function declaration and function expression equally. The parser will first read the function declaration and make it available (accessible) before executing any code. As for the function expression, it must wait until the parser executes to its line of code, to be interpreted and executed. For example:

console.log(sum(10,10)); // 20 function sum(num1, num2){     return num1 + num2; }

The above code can run properly. Before the code is executed, the parser reads and adds the function declaration to the execution environment through a process called function declaration hoisting. When you evaluate the code, the JavaScript engine declares the functions for the first time and places them on the top of the source code tree. Therefore, even if the declared function code is behind the code that calls it, the JavaScript engine can also promote the function declaration to the top. Changing the "function declaration" above to an equivalent "function expression" causes an error during execution. For example:

console.log(sum(10,10)); // Uncaught TypeError: sum is not a function var sum = function(num1, num2){     return num1 + num2; };

In addition to the preceding differences, the syntax of function declaration and function expression is equivalent.

Function as Value

Because the function name in JavaScript itself is a variable, the function can also be used as a value. That is to say, a function can be passed to another function just like a parameter, and a function can be returned as a result of another function. Let's take a look at the following functions.

function callSomeFunction(someFunction, someArgument){     return someFunction(someArgument); }

This function accepts two parameters. The first parameter should be a function, and the second parameter should be a value to be passed to the function. Then, you can pass functions as in the following example.

function add10(num){     return num + 10; }  var result1 = callSomeFunction(add10, 10); console.log(result1);   // 20  function getGreeting(name){     return "Hello, " + name; }  var result2 = callSomeFunction(getGreeting, "Nicholas"); console.log(result2);   // "Hello, Nicholas"

The callSomeFunction () function is universal, that is, no matter what function is passed in the first parameter, it returns the result after executing the first parameter. To access the function pointer without executing the function, you must remove the parentheses following the function name. Therefore, in the above example, add10 and getGreeting are passed to callSomeFunction (), rather than the results after they are executed.

Of course, you can also return another function from one function, which is also a very useful technology. For example, if there is an object array, we want to sort the Array Based on an object attribute. The comparison function passed to the array sort () method must receive two parameters, that is, the value to be compared. However, we need a way to specify which attribute to sort. To solve this problem, define a function that receives an attribute name and creates a comparison function based on the attribute name. The following is the definition of this function.

function createComparisonFunction(propertyName) {     return function(object1, object2){         var value1 = object1[propertyName];         var value2 = object2[propertyName];         if (value1 < value2){             return -1;         } else if (value1 > value2){             return 1;         } else {             return 0;         }     }; }

This function definition looks a bit complicated, but in fact it is nothing more than nesting another function in a function, and a return operator is added before the internal function. After the internal function receives the propertyName parameter, it uses square brackets to obtain the value of the given attribute. After obtaining the desired property value, it is very easy to define the comparison function. The above function can be used as in the following example.

var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];  data.sort(createComparisonFunction("name")); console.log(data[0].name);  // Nicholas  data.sort(createComparisonFunction("age")); console.log(data[0].name);  // Zachary

Here, we create an array of data containing two objects. Each object contains a name attribute and an age attribute. By default, the sort () method calls the toString () method of each object to determine their order. However, the result is often not in line with human thinking habits. Therefore, we call the createComparisonFunction ("name") method to create a comparison function to sort by the name attribute value of each object. The first item in the preceding figure is the object named "Nicolas" and age is 29. Then, we use the comparison function returned by createComparisonFunction ("age"), which is sorted by the age attribute of the object. The result is that the value of name is "Zachary", and the value of age is 28, which is the first object.

Function parameters and real parameters

Within the function, there are two special objects: arguments and this. Arguments is a class array object that contains all the parameters in the input function. Although the main purpose of arguments is to save function parameters, this object also has a property named callee, which is a pointer pointing to a function that owns this arguments object. See the following classic factorial function.

function factorial(num){ if (num <= 1) {         return 1;     } else {         return num * factorial(num-1)     } }

Recursive Algorithms are generally used to define factorial functions. As shown in the code above, when a function has a name and its name will not change in the future, this definition is correct. But the problem is that the execution of this function is closely coupled with the function name factorial. To eliminate this tight coupling, you can use arguments. callee as follows.

function factorial(num){     if (num <=1) {         return 1;     } else {         return num * arguments.callee(num-1)     } }

In the function body of the rewritten factorial () function, the function name factorial is no longer referenced. In this way, no matter what name is used when the function is referenced, the recursive call can be completed normally. For example:

var trueFactorial = factorial;  factorial = function(){     return 0; };  console.log(trueFactorial(5));  // 120 console.log(factorial(5));      // 0

Here, the trueFactorial variable obtains the value of factorial. In fact, it stores the pointer of a function in another position. Then, we assign a function that returns 0 to the factorial variable. If arguments. callee is not used as in the original factorial (), call trueFactorial () and 0 is returned. However, after the code in the function body is removed from the coupling state of the function name, trueFactorial () can still calculate the factorial normally; as for factorial (), it is only a function that returns 0.

Another special object inside the function is this, which is similar to this in Java and C. In other words, this references the environment object where function data is executed (when a function is called in the global scope of the webpage, this object references window ). Let's look at the example below.

window.color = "red"; var o = { color: "blue" };  function sayColor(){     console.log(this.color); } sayColor();     // "red"  o.sayColor = sayColor; o.sayColor();   // "blue"

The above function sayColor () is defined in the global scope and references this object. Because the value of this is unknown before the function is called, this may reference different objects during code execution. When sayColor () is called in the global scope, this references the Global Object window. In other words, this. the color value is converted to window. after the color is evaluated, "red" is returned ". When this function is assigned to the object o and called o. when sayColor (), this references object o, so this. the color value is converted to o. after the color is evaluated, "blue" is returned ".

Please remember that the function name is just a variable containing pointers. Therefore, even in different environments, the global sayColor () function and o. sayColor () point to the same function.

ECMAScript 5 standardizes the property caller of another function object. This attribute stores "reference to the function that calls the current function". If you call the current function in a global scope, its value is null. For example:

function outer(){     inner(); }  function inner(){     console.log(arguments.callee.caller); }   outer();

The above code will display the source code of the outer () function in the warning box. Because outer () calls inter (), arguments. callee. caller points to outer ().

In strict mode, accessing the arguments. callee attribute or assigning values to the caller attribute of the function will cause errors.

Function Attributes and Methods

Functions in JavaScript are objects, so functions also have attributes and methods. Each function has two attributes: length and prototype. The length attribute indicates the number of name parameters that the function wants to receive, as shown in the following example.

function sayName(name){     console.log(name); }  function sum(num1, num2){     return num1 + num2; }  function sayHi(){     console.log("hi"); }  console.log(sayName.length);      // 1 console.log(sum.length);          // 2 console.log(sayHi.length);        // 0

For reference types in JavaScript, prototype is the true method for saving all their instances. In other words, methods such as toString () and valueOf () are actually stored in the prototype name, but accessed through the instance of their respective objects. When creating a custom reference type and implementing inheritance, the role of the prototype attribute is extremely important. In ECMAScript 5, the prototype attribute cannot be enumerated, so it cannot be found using for-in.

Each function contains two non-inherited methods: apply () and call (). The purpose of these two methods is to call a function in a specific scope, which is actually equal to setting the value of this object in the function body. First, the apply () method receives two parameters: one is the scope in which the function is run, and the other is the parameter array. The second parameter can be an Array instance or an arguments object. For example:

Function sum (num1, num2) {return num1 + num2;} function callSum1 (num1, num2) {return sum. apply (this, arguments); // input arguments object} function callSum2 (num1, num2) {return sum. apply (this, [num1, num2]); // input an array} console. log (callSum1 (10, 10); // 20 console. log (callSum2 (10, 10); // 20

In the above example, callSum1 () passed this (because it is called in the global scope, so it is passed in the window object) and arguments object when executing the sum () function. CallSum2 also calls the sum () function, but it imports this and a parameter array. Both functions run normally and return correct results.

The call () method and the apply () method have the same effect. The difference is that the method of receiving parameters is different. For the call () method, the first parameter is that the value of this has not changed, and all other parameters are directly transferred to the function. In other words, when using the call () method, the parameters passed to the function must be listed one by one, as shown in the following example.

function sum(num1, num2){     return num1 + num2; }  function callSum(num1, num2){     return sum.call(this, num1, num2); }  console.log(callSum(10,10));   // 20

When the call () method is used, callSum () must explicitly input each parameter. The result is no different from apply. The use of apply () or call () depends entirely on the method you use to pass parameters to the function. If you want to directly pass in the arguments object or include an array that is first received by the function, it is more convenient to use apply (). Otherwise, call () may be more suitable. (It doesn't matter which method to use without passing parameters to the function .)

In fact, passing parameters are not really useful for both apply () and call (). What they really powerful about is the ability to expand the scope on which the function depends. The following is an example.

window.color = "red"; var o = { color: "blue" };  function sayColor(){     console.log(this.color); } sayColor();                // red  sayColor.call(this);       // red sayColor.call(window);     // red sayColor.call(o);          // blue

This example is modified based on the preceding example of this object. This time, sayColor () is also defined as a global function, and when it is called in a global scope, it does display "red", because for this. the value of color is converted to window. evaluate the color. SayColor. call (this) and sayColor. call (window) are two methods to explicitly call a function in the global scope, and the result will certainly display "red ". However, when sayColor. call (o) is run, the execution environment of the function is different, because the this object in the function body points to o, and the result is displayed as "blue ".

The biggest benefit of using call () or apply () to expand the scope is that the object does not need to have any coupling relationship with the method. In the first version of the previous example, we first put the sayColor () function into the object o, and then call it through o. In the example rewritten here, there is no need for the previous redundant steps.

Level

// Challenge 1: merge any number of strings var concat = function () {// method body to be implemented} console. log (concat ('st', 'on', 'E'); // stone // Challenge 2: output the Fibonacci series var fioacciSequece = function (count) at the specified position) {// method body to be implemented} console. log (fioacciSequece (12); // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 // Challenge 3, 3D array or n-dimensional array deduplication, use arguments to override var arr = [2, 3, 4, [2, 3, 2, 4], 5], 3, 5, [2, 3, 2, 3, 3, 2, 3, 2, 3, 2, 3, 4,2], 2], 4,3, 6,2]; var unique = function (arr) {// method body to be implemented} console. log (unique (arr); // [2, 3, 4, 5, 6]
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.