A method that allows JavaScript to have programming capabilities similar to Lambda expressions

Source: Internet
Author: User

However, I also told people that, because too many parameters are accepted, I often don't know how to use smart prompts unless I write them clearly.

However, when many parameters are accepted, in addition to making mistakes, there will be another problem, which is also the reason why I wrote this article published today.
Let's take a look at the Javascript version's page number to display the complete function signature of the component:
Copy codeThe Code is as follows:
Function pnView (
CurrentPage, actionCurrent,
BeginPage, endPage,
ActionBegin, actionEnd,
CurrentSiblings, actionCurrentSibling,
PreventFolding, actionFolding,
EndOfBegin, beginOfEnd,
ActionBeginSibling, actionEndSibling
)

As you can see, this can be used to customize the full function signature to the maximum extent. 14 parameters are accepted, and half of them-that is, 7 parameters-must accept the callback function.
The problem is that you need to manually write multiple character combinations such as "function () {}", like this:
Copy codeThe Code is as follows:
Function ww (s) {document. write (s );}
Function ws (n) {ww ('<A href = "#"> (' + n + ') </A> ');}
PnView (14, function (n) {ww ('[' + n + ']')},
1, 27,
Function (n) {ww ('<A href = "#" >|<' + n +' </A> ') ;}, function (n) {ww ('<A href = "#">' + n + '>|</A> ');},
2, ws,
1, function () {ww ('...');},
2, 2,
Ws, ws
);

When I test this component on a webpage, I feel that I miss Lambda expressions in C # very much. Although some people and some JS frameworks call anonymous functions "Lambda expressions ", but in fact it is only equivalent to "anonymous Delegate/function" in C #, while Lambda (surface) features use a short syntax mode to reflect a (callback) function/process (or action) logic, instead of being "delegate" or other keywords.

For this reason, I have compiled this module that can translate JS Code and translate a specific pattern into a function definition.
After using this module, the previous call can look like this:
Copy codeThe Code is as follows:
Eval (function (){
Var ww = (s, document. write (s ));
Var ws = (n, ww ('<A href = "#"> (' + n + ') </A> '));
PnView (14, (n, ww ('[' + n + ']'),
1, 27,
(N, ww ('<A href = "#"> | <' + n + '</A>'), (n, ww ('<A href = "#">' + n + '>|</A> ')),
2, ws,
1, (0, ww ('...')),
2, 2,
Ws, ws
);
}. Lamda ())();

The complete code of the module is as follows:
Copy codeThe Code is as follows:
/*!
L-amda "a-Lambda", a module provides Alternate "Lambda" style programming ability for JavaScript.
Created By NanaLich. 2010-09-08
This module is published under WTFPL v2, so you just do what the Fxxx you want to with it.
*/
! Function (){
Function attachEntry (o, a, m ){
Var I, j, n;
O = []. concat (o );
// If (! (O instanceof Array) o = [o];
While (I = o. shift ()){
For (j in ){
If (! I [n = a [j]) I [n] = m;
}
}
}
Var rx0 =/^ \ s * (0 | NaN | null) \ s *, $ /;
Var rx1 =/([\ W] \ s *) \ (\ s * 0 \ s *, | (? : \ S * [a-z _ $] [\ w $] * \ s *,) +) | "(\ [\ s \ S] | [^ \ x22]) *" | '(\ [\ s \ S] | [^ \ x27]) * '/gi;
Var rx2 = //)/g;
Function rxGetFlags (rx) {// retrieve the option for creating a regular expression
Return (rx. global? 'G': '') + (rx. ignoreCase? 'I': '') + (rx. multiline? 'M ':'');
// Return/\/([gim] *) $/. exec (''+ rx) [1];
}
AttachEntry (RegExp, ['getflags'], rxGetFlags );
AttachEntry (RegExp. prototype, ['getflags'], function (){
Return rxGetFlags (this );
});

Function translateLambda (s ){
If (typeof (s )! = 'String') s = ''+ s;
Var x = new RegExp (rx1.source, rx1.getFlags ());
Var y = new RegExp (rx2.source, rx2.getFlags (); // because firefox, safari, and other browsers have over-optimized global matching regular expressions, so here we use a roundabout method to create a regular expression instance that does not repeat
Var m, l = 0, r = '';
While (m = x.exe c (s )){
Var c = m [0], h, p, q, t;
Switch (c. charAt (0) {// determine the expected syntax
Case '$ ':
Case ')':
Case ']':
Case '"':
Case "'":
Continue; // parameter passing by function, skip
}

H = m [2];
If (rx0.test (h ))
H = '';
Else
H = h. substr (0, h. length-1); // remove the end comma
R + = s. substring (l, p = m. index); // Add the remaining content to the result string.
Y. lastIndex = l = p + c. length; // start searching for the right brackets after the comma.
While (q = y.exe c (s )){
Q = q. index;
Try {
T = 'Return '+ s. substring (l, q) + ';';
New Function (t); // syntax Test
// R + = c + 'function ('+ h +') {'+ translateLambda (t) +'} '; // translation content
R + = m [1] + 'function ('+ h +') {'+ translateLambda (t) +'} '; // translation content
X. lastIndex = l = q + 1; // The next query starts after the brackets.
Break;
} Catch (ex ){}
}
If (! Q) l = p; // It indicates that no right brackets or valid code can be found, and all matching content can be appended directly.
}
Try {
R + = s. substr (l );
If (/[\ w $] * | "(\ [\ s \ S] | [^ \ x22]) * "| '(\ [\ s \ S] | [^ \ x27]) *'/. exec (r) [0] = 'function') // roughly checks whether the generated function is a function (which can handle most cases)
R = '0, '+ r; // use this strange form to achieve the expected results in all browsers (including IE)
New Function (r); // syntax Test
Return r;
} Catch (ex) {// failed. The original text is returned.
Return s;
}
};

Var lamdaAliases = ["translatelames", "lambda", "lamda"];
AttachEntry ([Function, String], lamdaAliases, translatelames );
AttachEntry ([Function. prototype, String. prototype], lamdaAliases, function (){
Return translateLambda (this );
});
}();

Compared with Lambda expressions in C #, I still have many shortcomings in this module, but now I am very satisfied with this, at least I don't need to write too many "functions" anymore.
In short, the specification of this module is like this --
Advantages:
Reduce the number of times that "function" appears when writing code;
Use the pattern that can be normally edited in the general JavaScript editor and directly write it in the function body without causing syntax errors.
Limitations:
To use this module at any time, you must call the translation methods ("translateLambda", "lambda", or "lamda") and eval functions, which cannot be omitted;
If A function A exists, it is impossible to translate the parameters passed to A by processing a (that is,. lambda () or similar operations do not equate a (x, x * 2) with a (function (x) {return x * 2 ;}));
It cannot contain any statement other than the expression or multiple statements separated.
Disadvantages:
The continuous appearance of parentheses may make the code hard to understand;
No editor can provide syntax highlighting for Lambda expressions;
There is a possibility of incorrectly translating existing code-this module selects a pattern for matching which has no practical value in the normal code and usually does not appear, for example: (x, x * 2) is equivalent to x * 2, (0,. method () is equivalent to. method (), so the possibility of affecting the actual code is infinitely close to 0.
The following are some improper usage:
1. Using this module will not save a lot of code: put the cart before the horse.
Copy codeThe Code is as follows:
Eval (function () {// not only does not reduce the amount of code, but also increases
Window. onload = (0, alert ('loading complete! '));
}. Lambda ());

2. Translate functions that accept parameters: this situation has been mentioned before.
Copy codeThe Code is as follows:
Eval (somefunction. lambda () (x, x. toString (16); // somefunction may produce unexpected results, and the received parameter will be x. the result of toString (16) (if x is not defined here, an exception "the variable does not exist" will be generated), rather than a callback function.

3. Avoid syntax check to use this module:
Because the syntax is valid in JavaScript but has no practical value, it is completely unnecessary to avoid syntax checks.
Copy codeThe Code is as follows:
Eval ("somefunction (x, x. toString (16)". lamda (); // The syntax check is lost, and an exception may occur during running.

4. Use too many operations or even multiple statements in (pseudo) Lambda:
When designing this module, I did not find the pattern that can use multiple statements and pass the syntax check. The reason is that when multiple statements are used in Lambda expressions, the amount of code added by "function", "return", and other characters is usually negligible. Using Lambda expressions itself is a method that deviates from the original intention.
Copy codeThe Code is as follows:
Eval (function () {somefunction (x, y. something (x); return x. toString (16 )));}. lamda (); // syntax error
Eval (function () {somefunction (x, y. something (x), x. toString (16 )));}. lamda (); // It is easy to produce ambiguity in understanding.
Eval (function () {somefunction (x, ++ x) ;}. lamda (); // a simple expression can be accepted.

Best use cases:
Many people now like to write their code in a closure when writing JavaScript, which can avoid global scope pollution, just like this:
Copy codeThe Code is as follows:
(Function (){
// Put all the code here
})();

-- This "big" closure is the best place to use this module:
Copy codeThe Code is as follows:
Eval (function () {// Add eval before brackets
// Put all the code here
}. Lamda (); // Add. lamda () in brackets ()

Codeplex went crazy yesterday, causing errors in code and release uploads. Considering that the use of this module is relatively limited, it is not suitable for those who lack JavaScript experience, so it does not provide source code packaging and download-if necessary, copy it directly from the text.

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.