Home >Web Front-end >JS Tutorial >Methods to give JavaScript similar programming capabilities as Lambda expressions_javascript skills

Methods to give JavaScript similar programming capabilities as Lambda expressions_javascript skills

WBOY
WBOYOriginal
2016-05-16 18:19:441496browse

But I later told people that because it accepts too many parameters, if the smart prompts are not clearly written, even I often can’t figure out how to use them.

However, accepting many parameters will not only make it easier to use them incorrectly, but also cause another problem. This is why I wrote the thing released today.
Let’s take a look at the full function signature of the JS version of the page number rendering component:

Copy the code The 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 fully customized function signature accepts 14 parameters, half of which - that is 7 parameters are required to accept the callback function.
The resulting problem is that you need to manually write multiple "function(){}" and other character combinations, like this:
Copy code The code is as follows:

function ww(s) { document.write(s); }
function ws(n) { ww(' (' n ') '); }
pnView(14, function (n) { ww(' [' n '] ') },
1, 27,
function (n) { ww('|< ' n ' '); }, function (n) { ww(' ' n ' >|'); },
2, ws,
1, function () { ww(' ... '); },
2, 2,
ws, ws
);

When I tested this component on the web page, I felt that I missed the Lambda expression in C# - although Some people and some JS frameworks will call anonymous functions "Lambda expressions", but in fact that is only equivalent to "anonymous delegates/functions" in C#, and the (surface) characteristic of Lambda is to use a short syntax pattern to reflect a (Callback) function/procedure (or action) logic without being distracted by "delegate" or other keywords.

For this reason, I wrote this module that can translate JS code and translate a specific pattern into function definitions.
After using this module, the previous call can become like this:
Copy code The code is as follows:

eval(function () {
var ww = (s, document.write(s));
var ws = (n, ww(' (' n ') '));
pnView(14, (n, ww(' [' n '] ')),
1, 27,
(n , ww('|< ' n ' ')), (n, ww(' ' n ' > |')),
2, ws,
1, (0, ww(' ... ')),
2, 2,
ws, ws
);
}.lamda())();
The complete code of the
module is as follows:
Copy code The 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 a) {
if (!i[n = a[j]]) i[n] = m;
}
}
}
var rx0 = /^s*(0|NaN|null)s*,$/;
var rx1 = /([W]s*)((s*0s*,|(?:s*[a-z_$][w$]*s*,) )|"(\[sS]|[^x22])*"|'(\[sS]|[^x27])*'/gi;
var rx2 = /)/g;
function rxGetFlags(rx) { // 取出正则表达式的创建选项
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()); // 由于firefox、safari等浏览器对全局匹配正则表达式有过度的优化,所以这里采用一种迂回的办法创建不重复的正则表达式实例
var m, l = 0, r = '';
while (m = x.exec(s)) {
var c = m[0], h, p, q, t;
switch (c.charAt(0)) { // 判断期待的语法成分
case '$':
case ')':
case ']':
case '"':
case "'":
continue; // 函数传参,跳过
}

h = m[2];
if (rx0.test(h))
h = '';
else
h = h.substr(0, h.length - 1); // 去掉末尾的逗号
r = s.substring(l, p = m.index); // 在结果字符串上附加之前余留的内容
y.lastIndex = l = p c.length; // 从逗号之后开始寻找右括号
while (q = y.exec(s)) {
q = q.index;
try {
t = 'return ' s.substring(l, q) ';';
new Function(t); // 语法测试
//r = c 'function(' h '){ ' translateLambda(t) ' }'; // 翻译里面的内容
r = m[1] 'function(' h '){ ' translateLambda(t) ' }'; // 翻译里面的内容
x.lastIndex = l = q 1; // 下一次查找从括号之后开始
break;
} catch (ex) { }
}
if (!q) l = p; // 说明找不到右括号或者有效的代码,直接附加所有匹配的内容
}
try {
r = s.substr(l);
if (/[w$]*|"(\[sS]|[^x22])*"|'(\[sS]|[^x27])*'/.exec(r)[0] == 'function') // 粗略判断产生的是不是函数(可以应付绝大部分情况)
r = '0,' r; // 使用这种“怪”形式可以在所有浏览器(包括IE)中得到预期的效果
new Function(r); // 语法测试
return r;
} catch (ex) { // 失败,返回原文
return s;
}
};

var lamdaAliases = ["translateLambda", "lambda", "lamda"];
attachEntry([Function, String], lamdaAliases, translateLambda);
attachEntry([Function.prototype, String.prototype], lamdaAliases, function () {
return translateLambda(this);
});
} ();

如果和C#中的Lambda表达式相比的话,我的这个模块还是有很多不足的,不过现在这个样子已经让我很满意了,至少我不用再写太多的“function”了。
简单来说,这个模块的规格特性是这样的——
优点:
减少编写代码时“function”的出现次数;
使用可以在一般的JavaScript编辑器中正常编辑的语法模式(pattern),直接写在函数体中不会导致语法错误。
局限性:
在任何时候使用这个模块都必须调用转译方法(“translateLambda”、“lambda”或者“lamda”)和eval函数,无法省略;
如果存在一个函数A,不可能通过对A进行处理来达到转译传递至A的参数的目的(也就是说a.lambda()或者类似的操作并不会让a((x, x * 2))等同于a(function(x){ return x * 2; }));
不能包含表达式之外的任何语句、不能包含使用“;”来分隔的多条语句。
缺点:
连续出现的括号可能会让代码变得难以理解;
任何编辑器都无法为Lambda表达式提供语法高亮;
存在错误地转译现有代码的可能性——这个模块选择进行匹配的模式是在正常的代码中没有实用价值、也通常不会出现的模式,如:(x, x * 2)等价于单纯的x * 2、(0, a.method())等价于单纯的a.method(),所以这个缺点影响到实际代码的可能性无限趋近于0。
以下是几种不当的用法:
1、使用这个模块并不会节省很多代码量的时候:本末倒置。
复制代码 代码如下:

eval(function(){ // Not only did it not reduce the amount of code, but it also increased
window.onload = (0, alert('Loading completed!'));
}. lambda());

2. Translate functions that accept parameters: This situation has been mentioned before.
Copy code The code is as follows:

eval(somefunction.lambda())((x, x.toString(16))); // some function may produce unexpected results, and the parameters received will be the results of x.toString(16) (if x has not been defined here, it will also produce a "variable does not exist" exception), rather than a callback function.

3. Avoiding syntax checking in order to use this module:
Because you are using syntax that is valid in JavaScript but has no practical value, there is no need to circumvent syntax checking.
Copy code The code is as follows:

eval("somefunction((x, x.toString( 16)))".lamda()); // Loss of syntax checking, may cause accidents during runtime

4. Use too many operations in (pseudo) Lambda, even more Statements:
When designing this module, I did not find a pattern that can use multiple statements and pass the syntax check. The reason is that when using multiple statements in a Lambda expression, "function", The amount of code added by a few characters such as "return" is usually negligible. Using Lambda expressions in this way deviates from the original intention.
Copy code The 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 cause ambiguity in understanding
eval(function(){ somefunction((x, x)); }.lamda()) (); // Simple expressions can be accepted

Best use cases:
Many people now like to write their code in a closure when writing JavaScript, like this You can avoid the global scope pollution problem, like this:
Copy the code The code is as follows:

(function(){
// All the code is placed here
})();

- and this "big" closure happens to use this module Best occasion:
Copy code The code is as follows:

eval(function(){ // Add eval before the brackets
// All the code is placed here
}.lamda())(); // Add .lamda() inside the brackets

Codeplex went crazy yesterday , there are always errors in code and release uploads. Considering that the use cases of this module are relatively limited and not suitable for people who lack JavaScript experience, the source code is not packaged and downloaded separately - please copy it directly from the text if necessary.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn