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


Posted in Javascript onSeptember 14, 2010

在发了博文之后,我又花了一些时间尝试解决这个问题……经过几次尝试之后,我找到了另一种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等浏览器对全局匹配正则表达式有过度的优化,所以这里采用一种迂回的办法创建不重复的正则表达式实例 
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 相关文章推荐
客户端脚本中常常出现的一些问题和调试技巧
Jan 09 Javascript
Javascript打印网页部分内容的脚本
Nov 17 Javascript
AngularJS初始化过程分析(引导程序)
Dec 06 Javascript
JS点击链接后慢慢展开隐藏着图片的方法
Feb 17 Javascript
jquery实现右键菜单插件
Mar 29 Javascript
jQuery Real Person验证码插件防止表单自动提交
Nov 06 Javascript
node.js中debug模块的简单介绍与使用
Apr 25 Javascript
javascript 中select框触发事件过程的分析
Aug 01 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
Aug 20 Javascript
在Chrome DevTools中调试JavaScript的实现
Apr 07 Javascript
vue 自定指令生成uuid滚动监听达到tab表格吸顶效果的代码
Sep 16 Javascript
Javascript实现贪吃蛇小游戏(含详细注释)
Oct 23 Javascript
手把手教你自己写一个js表单验证框架的方法
Sep 14 #Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
Sep 14 #Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
Sep 14 #Javascript
基于jquery的划词搜索实现(备忘)
Sep 14 #Javascript
基于jquery的页面划词搜索JS
Sep 14 #Javascript
基于Jquery的实现回车键Enter切换焦点
Sep 14 #Javascript
js输出列表实现代码
Sep 12 #Javascript
You might like
第十一节 重载 [11]
2006/10/09 PHP
使用ThinkPHP+Uploadify实现图片上传功能
2014/06/26 PHP
CodeIgniter与PHP5.6的兼容问题
2015/07/16 PHP
CentOS下PHP7的编译安装及MySQL的支持和一些常见问题的解决办法
2015/12/17 PHP
php session实现多级目录存放实现代码
2016/02/03 PHP
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
跟着JQuery API学Jquery 之三 筛选
2010/04/09 Javascript
jQuery点击后一组图片左右滑动的实现代码
2012/08/16 Javascript
为指定的元素添加遮罩层的示例代码
2014/01/15 Javascript
使用PHP+JavaScript将HTML页面转换为图片的实例分享
2016/04/18 Javascript
onmouseover事件和onmouseout事件全面理解
2016/08/15 Javascript
Vue 2.0 服务端渲染入门介绍
2017/03/29 Javascript
Bootstrap Tree View简单而优雅的树结构组件实例解析
2017/06/15 Javascript
vue-router实现tab标签页(单页面)详解
2017/10/17 Javascript
JointJS流程图的绘制方法
2018/12/03 Javascript
layui使用数据表格实现购物车功能
2019/07/26 Javascript
webpack+vue.js构建前端工程化的详细教程
2020/05/10 Javascript
Nuxt默认模板、默认布局和自定义错误页面的实现
2020/05/11 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
[01:01:25]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第三局
2016/02/27 DOTA
[01:02:05]LGD vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
浅谈numpy生成数组的零值问题
2018/11/12 Python
python画图——实现在图上标注上具体数值的方法
2019/07/08 Python
在pycharm中实现删除bookmark
2020/02/14 Python
Sephora丝芙兰澳洲官方网站:国际知名化妆品购物
2016/10/27 全球购物
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
2016/04/15 面试题
会计毕业生自我鉴定
2013/11/04 职场文书
园林设计师自荐信
2013/11/18 职场文书
药学专业大专生的自我评价
2013/12/12 职场文书
电子商务求职信
2014/06/15 职场文书
医学求职自荐信
2014/06/21 职场文书
2014年教育实习工作总结
2014/11/22 职场文书
秋季运动会加油词
2015/07/18 职场文书
2019职场单身人才调研报告:互联网行业单身比例最高
2019/08/07 职场文书
为什么你写的height:100%不起作用
2021/05/10 HTML / CSS
灵能百分百第三季什么时候来?
2022/03/15 日漫