首頁 web前端 js教程 JavaScript具有类似Lambda表达式编程能力的代码(改进版)_javascript技巧

JavaScript具有类似Lambda表达式编程能力的代码(改进版)_javascript技巧

May 16, 2016 pm 06:19 PM
lambda

在发了博文之后,我又花了一些时间尝试解决这个问题……经过几次尝试之后,我找到了另一种pattern,括号并不再是必要的了:

复制代码 代码如下:

eval(function () {
var s = '', ww = [v] > (s += v);
var ws = [n] > ww(' (' + n + ') ');
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等浏览器对全局匹配正则表达式有过度的优化,所以这里采用一种迂回的办法创建不重复的正则表达式实例
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再次抽疯,这次还是没有下载。
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

lambda 表達式在 C++ 中如何處理異常? lambda 表達式在 C++ 中如何處理異常? Apr 17, 2024 pm 12:42 PM

在C++中,使用Lambda表達式處理異常有兩種方法:使用try-catch區塊捕獲異常,並在catch區塊中處理或重新拋出異常。使用std::function類型的包裝函數,其try_emplace方法可以捕獲Lambda表達式中的異常。

C++ lambda 表達式中閉包的意思是什麼? C++ lambda 表達式中閉包的意思是什麼? Apr 17, 2024 pm 06:15 PM

在C++中,閉包是能夠存取外部變數的lambda表達式。若要建立閉包,請擷取lambda表達式中的外部變數。閉包提供可重複使用性、資訊隱藏和延遲求值等優點。它們在事件處理程序等實際情況中很有用,其中即使外部變數被銷毀,閉包仍然可以存取它們。

用 C++ lambda 表達式實作多執行緒程式設計的優點是什麼? 用 C++ lambda 表達式實作多執行緒程式設計的優點是什麼? Apr 17, 2024 pm 05:24 PM

lambda表達式在C++多執行緒程式設計中的優點包括:簡潔性、靈活性、易於傳參和並行性。實戰案例:使用lambda表達式建立多執行緒,在不同執行緒中列印執行緒ID,展示了該方法的簡潔和易用性。

C++ Lambda 表達式如何實作閉包? C++ Lambda 表達式如何實作閉包? Jun 01, 2024 pm 05:50 PM

C++Lambda表達式支援閉包,即保存函數作用域變數並供函數存取。語法為[capture-list](parameters)->return-type{function-body}。 capture-list定義要捕獲的變量,可以使用[=]按值捕獲所有局部變量,[&]按引用捕獲所有局部變量,或[variable1,variable2,...]捕獲特定變量。 Lambda表達式只能存取捕獲的變量,但無法修改原始值。

C++ lambda 表達式如何捕捉外部變數? C++ lambda 表達式如何捕捉外部變數? Apr 17, 2024 pm 04:39 PM

在C++中捕捉外部變數的lambda表達式有三種方法:按值擷取:建立一個變數副本。按引用擷取:獲得變數引用。同時按值和引用捕獲:允許捕獲多個變量,按值或按引用。

C++ 函式呼叫 Lambda 表達式:參數傳遞與傳回值的回呼最佳化 C++ 函式呼叫 Lambda 表達式:參數傳遞與傳回值的回呼最佳化 May 03, 2024 pm 12:12 PM

在C++中,可以使用Lambda表達式作為函數參數,實現回呼函數的靈活性。具體而言:參數傳遞:透過std::function包裝Lambda表達式,以函數指標形式傳遞給函數。傳回值處理:使用std::function宣告回呼函數指標時指定傳回值類型。實戰案例:優化GUI事件處理中的回調,避免創建不必要的物件或函數指針,提高程式碼簡潔性和可維護性。

如何使用 C++ lambda 表達式執行延遲求值? 如何使用 C++ lambda 表達式執行延遲求值? Apr 17, 2024 pm 12:36 PM

如何使用C++lambda表達式執行延遲求值?使用lambda表達式建立延遲求值的函數物件。延遲計算推遲到需要時才執行。僅當需要時才計算結果,提高效能。

如何用 C++ lambda 表達式取代函數指標? 如何用 C++ lambda 表達式取代函數指標? Apr 17, 2024 pm 04:24 PM

以lambda表達式取代函數指標可提升可讀性、減少樣板程式碼並提高重用性。具體而言,lambda表達式採用以下語法:[capturelist](parameterlist)->returntype{body},並可用於對向量排序等實戰案例中,提升程式碼簡潔性和可維護性。

See all articles