JavaScript具有类似Lambda表达式编程能力的代码(改进版)
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
发布时间:2016-12-30 来源:查字典编辑
摘要:在发了博文之后,我又花了一些时间尝试解决这个问题……经过几次尝试之后,我找到了另一种pattern,括号并不再是必要的了:复制代码代码如下:...

在发了博文之后,我又花了一些时间尝试解决这个问题……经过几次尝试之后,我找到了另一种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 = /"(?:[sS]|[^x22])*"|'(?:[sS]|[^x27])*'|([^sw]s*)[(s*|s*[A-Z$_][w$]*s*(?:,s*[A-Z$_][w$]*s*)*)]s*(>)s*((?)/gi;

var xy = /[nr),;]}]|$/.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再次抽疯,这次还是没有下载。

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类