The role of JavaScript design pattern is to improve the reusability and readability of the code, making the code easier to maintain and expand.
In javascript, a function is a class of objects, which means that it can be passed as a parameter to other functions; in addition, the function can also provide scope.
Syntax for creating a function
Named function expressions
//Name function expression var add = function add(a,b){ return a+b;};var foo = function bar() { console.log(foo === bar);};foo();//trueIt can be seen that they are referring to the same function, but this is only valid in the function body.
var foo = function bar() {};console.log(foo === bar);//ReferenceError: bar is not definedHowever, you cannot call the function by calling bar().
var foo = (function bar() { console.log(foo === bar);})();//falseFunction expressions
//Also known as the anonymous function var add = function(a,b){ return a+b;};The value assigned to the variable add is the function definition itself. In this way, add becomes a function that can be called anywhere.
Declaration of functions
function foo(){ //code here} //There is no need for semicolons hereIn trailing semicolons, function expressions should always use semicolons, and the ending of semicolons is not required in the function's declaration.
The difference between a declarative function and a function expression is that during the precompilation period of JS, the declarative function will be extracted first, and then the js code will be executed in order:
console.log(f1);//[Function: f1]
console.log(f2);//undefined, Javascript is not fully interpreted and executed in order, but will "precompile" the Javascript before interpretation. During the precompilation process, the definitive function will be executed first.
function f1(){ console.log("I am f1");}var f2 = function (){ console.log("I am f2");};Since declaring functions will be completed during global scope construction, declaring functions are properties of window objects, which shows why no matter where we declare functions, declaring functions ultimately belong to window objects.
In the JavaScript language, any anonymous function belongs to a window object. When defining an anonymous function, it will return its memory address. If a variable receives this memory address at this time, the anonymous function can be used in the program, because the anonymous function is also defined and assigned during the global execution environment construction, so this pointing of the anonymous function is also a window object
var f2 = function (){ console.log("I am f2");};console.log(f2());//I am f2(function(){ console.log(this === window);//true})();Function declarations and expressions
Function promotion (hoisting)
The behavior of a function declaration is not equivalent to a named function expression. The difference is the hoisting behavior. See the following example:
<script type="text/javascript"> //Global function function foo(){alert("global foo!");} function bar(){alert('global bar');} function hoist(){ console.log(typeof foo);//function console.log(typeof bar);//undefined foo();//local foo! bar();//TypeError: 'undefined' is not a function //Variable foo and implementer are promoted function foo(){ alert('local foo!'); } //Only variable bar is promoted, the function implementation part is not promoted var bar = function(){ alert('local bar!'); }; } hoist(); </script>For all variables, wherever they are declared in the body, they are internally promoted to the top of the function. The reason for general application of functions is that functions are only objects assigned to variables.
As the name suggests, improvement means mentioning the following things to the top. In JS, it is to upgrade the things defined in the following (variables or functions) to the previous definition. As can be seen from the above example, foo and bar in the function hoist inside the function move to the top, thus covering the global foo and bar functions. The difference between local functions bar and foo is that foo is promoted to the top and can run normally, while the definition of bar() has not been improved, only its declaration is promoted. Therefore, when bar() is executed, the result is undefined instead of being used as a function.
Real-time function mode
Functions are also objects, so they can be used as return values. The advantage of using self-executing functions is to directly declare an anonymous function and use it immediately, so as to avoid defining a function that is not used once, and it is avoided from the problem of naming conflicts. There is no concept of namespace in js, so it is easy to have function name conflicts. Once a naming conflict is made, the last declared one shall prevail.
Mode 1:
<script> (function () { var a = 1; return function () { alert(2); }; }()());//2 pops up, the first parentheses execute themselves, and the second parentheses execute internal anonymous functions</script>Pattern 2: Pointing of self-executing function variables
<script type="text/javascript"> var result = (function () { return 2; })();//The function alert(result);//result points to the return value 2 of the self-executed function; if result() pops up, an error will occur</script>Pattern Three: Nested Functions
<script type="text/javascript"> var result = (function () { return function () { return 2; }; })(); alert(result());// When alert(result) function(){return 2}</script>Mode 4: Self-execution function assigns its return value to a variable
var abc = (function () { var a = 1; return function () { return ++a; } })();//The function of the self-executing function returns the function after return to the variable alert(abc());//If it is alert(abc), the code after the return statement will be popped up; if it is abc(), the function after return will be executedPattern 5: The function executes itself internally, recursively
// This is a self-executing function, the function executes itself internally, recursive function abc() { abc(); }Callback mode
Callback function: When you pass a function write() as an argument to another function call(), then call() may execute (or call) write() at some point. In this case, write() is called a callback function.
Asynchronous event listener
Callback mode has many uses, for example, when an event listener is attached to an element on the page, it actually provides a pointer to a callback function that will be called when the event occurs. like:
document.addEventListener("click",console.log,false);
The above code example shows the callback function console.log() in bubble mode when the document clicks.
JavaScript is especially suitable for event-driven programming, because callback mode supports programs to run asynchronously.
time out
Another example of using callback mode is when using the timeout method provided by the browser's window object: setTimeout() and setInterval(), such as:
<script type="text/javascript"> var call = function(){ console.log("100ms will be asked..."); }; setTimeout(call, 100);</script>Callback mode in the library
When designing a JS library, the callback function will come in handy. The code of a library should use reusable code as much as possible, and the callback can help achieve this generalization. When we design a huge js library, the fact is that users don't need most of it, we can focus on core functions and provide callback functions in "hook form", which will make it easier for us to build, scale, and customize library methods
Currying
Currying is a technique that converts a function into a new simplified (to fewer parameters) function by filling multiple parameters into a function body. ――【Proficient in JavaScript】
Simply put, curryization is a conversion process, that is, the process of our function conversion. As shown in the following example:
<script type="text/javascript"> //curry-based add() function function add(x,y){ var oldx = x, oldy = y; if(typeof oldy == "undefined"){ return function(newy){ return oldx + newy; }; } //completely apply return x+y; } //Test typeof add(5);//Output "function" add(3)(4);//7 //Create and store a new function var add2000 = add(2000); add2000(10);//Output 2010</script>When add() is called for the first time, it creates a closure for the returned internal function. This closure stores the original x and y values into the private variables oldx and oldy.
Now we will be able to use a general method of curry using any function, such as:
<script type="text/javascript"> //Ordinary function function add(x,y){ return x + y; } //curry a function to obtain a new function var newadd = test(add,5); newadd(4);//9 //Another option, directly call the new function test(add,6)(7);//Output 13</script>When to use Curry
When it is found that the same function is being called and most of the passed parameters are the same, then the function may be a good candidate for curryization