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 相关文章推荐
jQuery 常见开发使用技巧总结
Dec 26 Javascript
JavaScript Memoization 让函数也有记忆功能
Oct 27 Javascript
Jquery在指定DIV加载HTML示例代码
Feb 17 Javascript
JavaScript中神奇的call()方法
Mar 12 Javascript
js滚轮事件兼容性问题需要注意哪些
Nov 15 Javascript
jQuery 表单序列化实例代码
Jun 11 jQuery
jquery 输入框查找关键字并提亮颜色的实例代码
Jan 23 jQuery
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
Sep 26 Javascript
AngularJS 多指令Scope问题的解决
Oct 25 Javascript
简单通过settimeout看javascript的运行机制
May 10 Javascript
在Vue项目中用fullcalendar制作日程表的示例代码
Aug 04 Javascript
JavaScript 面向对象基础简单示例
Oct 02 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
初探PHP5
2006/10/09 PHP
PHP 长文章分页函数 带使用方法,不会分割段落,翻页在底部
2009/10/22 PHP
dedecms系统的广告设置代码 基础版本
2010/04/09 PHP
使用新浪微博API的OAuth认证发布微博实例
2015/03/27 PHP
ExtJS 学习专题(一) 如何应用ExtJS(附实例)
2010/03/11 Javascript
jQuery总体架构的理解分析
2011/03/07 Javascript
关于jQuery对象数据缓存Cache原理以及jQuery.data详解
2013/04/07 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
如何使用JS获取IE上传文件路径(IE7,8)
2013/07/08 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
2014/04/04 Javascript
JavaScript实现自动对页面上敏感词进行屏蔽的方法
2015/07/27 Javascript
基于jQuery通过jQuery.form.js插件使用ajax提交form表单
2015/08/17 Javascript
JS实现的网页背景闪电闪烁效果代码
2015/10/17 Javascript
easyui 中的datagrid跨页勾选问题的实现方法
2017/01/18 Javascript
bootstrap PrintThis打印插件使用详解
2017/02/20 Javascript
Restify中接入Socket.io报Error:Can’t set headers的错误解决
2017/03/28 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
easyui combogrid实现本地模糊搜索过滤多列
2017/05/13 Javascript
利用require.js与angular搭建spa应用的方法实例
2017/07/19 Javascript
js登录滑动验证的实现(不滑动无法登陆)
2018/01/03 Javascript
js数据类型检测总结
2018/08/05 Javascript
vue多级复杂列表展开/折叠及全选/分组全选实现
2018/11/05 Javascript
JS实现移动端可折叠导航菜单(现代都市风)
2020/07/07 Javascript
python中__slots__用法实例
2015/06/04 Python
深入浅出学习python装饰器
2017/09/29 Python
Python Process多进程实现过程
2019/10/22 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
Python 存取npy格式数据实例
2020/07/01 Python
基于Python实现简单学生管理系统
2020/07/24 Python
思想专业自荐信范文
2013/12/25 职场文书
酒店优秀员工事迹材料
2014/06/02 职场文书
卖车协议书范本4篇
2014/10/01 职场文书
优秀班主任推荐材料
2014/12/17 职场文书
导游词之江苏溱潼古镇
2019/11/27 职场文书
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android
Java GUI编程菜单组件实例详解
2022/04/07 Java/Android