JavaScript具有類似Lambda運算式編程能力的代碼(改進版)

來源:互聯網
上載者:User

在發了博文之後,我又花了一些時間嘗試解決這個問題……經過幾次嘗試之後,我找到了另一種pattern,括弧並不再是必要的了: 複製代碼 代碼如下:eval(function () {
var s = '', ww = [v] > (s += v);
var ws = [n] > ww(' <A href="#">(' + n + ')</A> ');
pnView3(14, [n] > ww(' [' + n + '] '),
1, 37,
ws, [] > ww(' ... '),
2, 1
);
document.write(s);
} .lamda0());

不過,由於運算子優先順序的關係,比較、門、賦值等運算子仍然不能直接寫在(偽)Lambda運算式中。
也就是說 複製代碼 代碼如下:function(a, b){ a == b }

仍然需要寫成 複製代碼 代碼如下:[a, b] > (a == b)

另外,選擇的pattern本身是具有實際效果的——當把一個數組和另一樣東西進行比較的時候,指令碼引擎會先嘗試把兩邊都轉化成數值,如果不成功就轉化成字串再比較。
不過我想正常情況下應該很少有人會拿數組跟別的東西這麼比——所以甚至不需要主動去避免,只要用不到(偽)Lambda運算式的時候不特意去這樣用就沒問題了。

新的實現代碼如下: 複製代碼 代碼如下:/*!
L-amda "a-Lambda", a module provides Alternate "Lambda" style programming ability for JavaScript.
Created By NanaLich. 2010-09-10
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);
while (i = o.shift()) {
for (j in a) {
if (!i[n = a[j]]) i[n] = m;
}
}
}
var xx = /"(?:\\[\s\S]|[^\x22])*"|'(?:\\[\s\S]|[^\x27])*'|([^\s\w]\s*)\[(\s*|\s*[A-Z$_][\w$]*\s*(?:,\s*[A-Z$_][\w$]*\s*)*)\]\s*(>)\s*(\(?)/gi;
var xy = /[\n\r),;\]}]|$/.source;
function rxClone(rx) {
return new RegExp(rx.source, (rx.global ? 'g' : '') + (rx.ignoreCase ? 'i' : '') + (rx.multiline ? 'm' : ''));
}
attachEntry(RegExp, ['clone'], rxClone);
attachEntry(RegExp.prototype, ['clone'], function () { return rxClone(this); });
function translateLambda(s) {
var m, l = 0, r = '', x = xx.clone(); // 由於firefox、safari等瀏覽器對全域匹配Regex有過度的最佳化,所以這裡採用一種迂迴的辦法建立不重複的Regex執行個體
while (m = x.exec(s)) {
var h = m[0];
switch (h.charAt(0)) { // 判斷期待的文法成分
case '$': // 函數傳參
case ')':
case ']':
case '"': // 匹配到了字串
case "'":
continue; // 以上皆跳過
}
var p, q, t, k = m[4].length, y = new RegExp(k ? '\\)' : xy, 'g');
r += s.substring(l, p = m.index); // 在結果字串上附加之前餘留的內容
y.lastIndex = l = p + h.length; // 從偽運算子之後開始尋找右括弧或者其它符號
while (q = y.exec(s)) {
q = q.index;
try {
t = 'return(' + s.substring(l, q) + ');';
new Function(t); // 文法測試
r += m[1] + 'function(' + m[2] + '){ ' + translateLambda(t) + ' }'; // 翻譯裡面的內容
x.lastIndex = l = q + k; // 下一次尋找從當前邊界之後開始
break;
} catch (ex) { }
}
if (!q) l = p; // 說明找不到右括弧或者有效代碼,直接附加所有匹配的內容
}
try {
r += s.substr(l);
new Function(r); // 文法測試
return r;
} catch (ex) { // 失敗,返回原文
return s;
}
};
var lamdaAliases = ["translateLambda", "lambda", "lamda"];
attachEntry(String, lamdaAliases, translateLambda);
attachEntry(String.prototype, lamdaAliases, function () { return translateLambda(this); });
var funPrototype = Function.prototype;
attachEntry(Function, lamdaAliases, function (func) { return translateLambda('0,' + func); });
attachEntry(funPrototype, lamdaAliases, function () { return translateLambda('0,' + this); });
var lamda0aliases = ['lambdaInit', 'lambda0', 'lamda0'];
attachEntry(Function, lamda0aliases, function (func) { return translateLambda('!' + func + '()'); });
attachEntry(funPrototype, lamda0aliases, function () { return translateLambda('!' + this + '()'); });
} ();

這次為函數增加了專門的方法,去掉了之前蹩足的判斷、也增加了新方法稍微簡化調用過程;
修正了有額外空格時無法判斷期望文法成分的BUG。

另外由於Codeplex再次抽瘋,這次還是沒有下載。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.