> 웹 프론트엔드 > JS 튜토리얼 > JavaScript에 Lambda 표현식_javascript 기술과 유사한 프로그래밍 기능을 제공하는 방법

JavaScript에 Lambda 표현식_javascript 기술과 유사한 프로그래밍 기능을 제공하는 방법

WBOY
풀어 주다: 2016-05-16 18:19:44
원래의
1494명이 탐색했습니다.

하지만 나중에 사람들에게 너무 많은 매개변수를 허용하기 때문에 스마트 프롬프트가 명확하게 작성되지 않으면 나조차도 사용법을 알 수 없는 경우가 많다고 말했습니다.

그러나 많은 매개 변수를 허용하면 잘못 사용하기 쉬울 뿐만 아니라 또 다른 문제가 발생할 수도 있습니다.
페이지 번호 렌더링 구성 요소 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、使用这个模块并不会节省很多代码时候:本末倒置。



复主代码代码如下:}.lambda());


2. 매개변수를 받는 함수 변환: 이 상황은 이전에 언급되었습니다.



코드 복사
코드는 다음과 같습니다. eval(somefunction.lambda())( (x, x.toString(16))); // 일부 함수는 예상치 못한 결과를 생성할 수 있으며, 수신된 매개변수는 x.toString(16)의 결과가 됩니다(여기서 x가 정의되지 않은 경우 콜백 함수가 아닌 "변수가 존재하지 않습니다" 예외).
3. 이 모듈을 사용하기 위해 구문 검사를 피하는 방법:
JavaScript에서는 유효하지만 실질적인 가치가 없는 구문을 사용하므로 구문 검사를 피할 필요가 없습니다.



코드 복사
코드는 다음과 같습니다. eval("somefunction((x, x .toString( 16)))".lamda()); // 구문 검사가 손실되어 런타임 중에 사고가 발생할 수 있습니다
4. (의사) Lambda에서 너무 많은 작업을 사용하고 더 많은 명령문을 사용합니다. :
이 모듈을 설계할 때 여러 문을 사용하고 구문 검사를 통과할 수 있는 패턴을 찾지 못했습니다. 그 이유는 람다 표현식에서 여러 문을 사용할 때 "함수"에 의해 추가되는 코드의 양 때문입니다. "return"과 같은 소수의 문자는 일반적으로 무시할 수 있습니다. 이런 방식으로 람다 표현식을 사용하면 원래 의도에서 벗어납니다.



코드 복사
코드는 다음과 같습니다. eval(function(){ somefunction(( x, y .something(x); return x.toString(16))); }.lamda())(); // 구문 오류eval(function(){ somefunction((x, y.something( x), x.toString(16))); }.lamda())(); // 이해가 모호해지기 쉽습니다
eval(function(){ somefunction((x, x)); } .lamda()) (); // 간단한 표현식을 사용할 수 있습니다


최고의 사용 사례:
이제 많은 사람들이 JavaScript를 작성할 때 클로저에 코드를 작성하는 것을 좋아합니다. 다음과 같이 전역 범위 오염 문제를 피하십시오.



코드를 복사하세요.
코드는 다음과 같습니다. (function(){ // 모든 코드는 여기에 배치됩니다
})()


- 이 "큰" 클로저는 이 모듈을 사용합니다.



코드 복사
코드는 다음과 같습니다. eval(function(){ // 추가 괄호 앞의 eval // 모든 코드는 여기에 배치됩니다
}.lamda())() // 괄호 안에 .lamda()를 추가합니다


어제 Codeplex가 미쳤습니다. , 코드 및 릴리스 업로드에는 항상 오류가 있습니다. 본 모듈의 사용 사례가 상대적으로 제한적이고 JavaScript 경험이 부족한 사람들에게는 적합하지 않다는 점을 고려하여 소스 코드는 별도로 패키지되어 다운로드되지 않습니다. 필요한 경우 텍스트에서 직접 복사하십시오.
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿