首页 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 05:45 PM

优化C++Lambda表达式的性能技巧包括:避免创建不必要的lambda对象通过std::bind显式捕获最小的对象使用std::move移动捕获的变量以避免复制优化lambda体,避免不必要的内存分配、重复计算和全局变量访问

See all articles