하지만 나중에 사람들에게 너무 많은 매개변수를 허용하기 때문에 스마트 프롬프트가 명확하게 작성되지 않으면 나조차도 사용법을 알 수 없는 경우가 많다고 말했습니다.
그러나 많은 매개 변수를 허용하면 잘못 사용하기 쉬울 뿐만 아니라 또 다른 문제가 발생할 수도 있습니다.
페이지 번호 렌더링 구성 요소 JS 버전의 전체 기능 서명을 살펴보겠습니다.
function pnView(
currentPage, actionCurrent,
beginPage, endPage,
actionBegin, actionEnd,
currentSiblings, actionCurrentSibling,
preventFolding , actionFolding,
endOfBegin, startOfEnd ,
actionBeginSibling, actionEndSibling
)
보시다시피 이 완전히 사용자 정의된 함수 시그니처는 14개의 매개변수를 허용하며 그 중 절반은 7개입니다. 콜백 함수를 수락하려면 매개변수가 필요합니다.
결과적인 문제는 다음과 같이 여러 "function(){}" 및 기타 문자 조합을 수동으로 작성해야 한다는 것입니다.
function ww(s) { document.write(s) }
function ws(n) { ww('
(' n ') ') }
pnView(14, function (n) { ww(' [' n '] ') },
1, 27 ,
함수 (n) { ww('
|< 'n ' ') }, 함수 (n) { ww('
' n ' >|') },
2, ws,
1, function () { ww(' ... ') }; 🎜 >2, 2,
ws, ws
)
웹 페이지에서 이 구성 요소를 테스트할 때 C#의 Lambda 표현식이 그리워졌다고 느꼈습니다. 일부 JS 프레임워크는 익명 함수를 "Lambda 표현식"이라고 부르지만 사실 이는 C#의 "익명 대리자/함수"와 동일하며 Lambda의 (표면) 특성은 짧은 구문 패턴을 사용하여 (콜백 ) "위임"이나 다른 키워드에 의해 산만해지지 않고 함수/절차(또는 동작) 논리.
이런 이유로 JS 코드를 변환하고 특정 패턴을 함수 정의로 변환할 수 있는 모듈을 작성했습니다.
이 모듈을 사용한 후 이전 호출은 다음과 같습니다.
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())();
모듈의 전체 코드는 다음과 같습니다.
복사 코드 코드는 다음과 같습니다.
/*!
L-amda "a-Lambda" 모듈은 JavaScript에 대한 대체 "Lambda" 스타일 프로그래밍 기능을 제공합니다.
NanaLich가 제작했습니다. 2010-09-08
이 모듈은 WTFPL v2에 따라 게시되었으므로 원하는 Fxxx 작업을 수행하면 됩니다.
*/
!function () {
function attachmentEntry(o, a, m) {
var i, j, n;
o = [].concat(o);
//if (!(o 배열 인스턴스)) 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 ? '중' : '');
//return //([gim]*)$/.exec('' rx)[1];
}
attachEntry(RegExp, ['getFlags'], rxGetFlags);
attachEntry(RegExp.prototype, ['getFlags'], function () {
return rxGetFlags(this);
});
functiontranslateLambda(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; ) { }
}
if (!q) l = p; // 说明找不到右括号或者有效的代码,直接附加所有匹配的内容
}
try {
r = s.substr(l);
if (/[w$]*|"(\[sS]|[^x22])*"|'(\[sS]|[^x27])*' /.exec(r)[0] == '함수') // 粗略判断产生的是不是函数(可以应付绝大分情况)
r = '0,' r // 使用这种“怪”형式可以현재所有浏览器(包括IE)中得到预期的效果
new Function(r); // 语法测试
return
} catch (ex) { // 失败,返回原文
s를 반환합니다;
}
};
var lamdaAliases = ["translateLambda", "lambda", "lamda"];
attachEntry([함수, 문자열], lamdaAliases, 번역Lambda);
attachEntry([Function.prototype, String.prototype], lamdaAliases, function () {
returntranslateLambda(this);
});
} ();
如果和C#中的Lambda表达式比的话,我的这个模块还是有很多不足的, 不过现个样子已经让我很满意了,至少我는 사용하지 않습니다. “함수”를 사용합니다.
简单来说, 这个模块的规格特性是这样的——
优点:
减少编写代码时“함수”를 출력합니다
使JavaScript를 사용하는 방법 |模块道必须调사용转译方法(“translateLambda”、“ 람다” 또는 “람다”) 및 평가판 函数 , 无법성 略;
就是说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、使用这个模块并不会节省很多代码时候:本末倒置。