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 相关文章推荐
javascript阻止scroll事件多次执行的思路及实现
Nov 08 Javascript
JavaScript阻止事件冒泡示例分享
Dec 28 Javascript
jQuery实现渐变弹出层和弹出菜单的方法
Feb 20 Javascript
jquery实现焦点图片随机切换效果的方法
Mar 12 Javascript
JavaScript Math.round() 方法
Dec 18 Javascript
学习vue.js计算属性
Dec 03 Javascript
自动适应iframe右边的高度
Dec 22 Javascript
Angular2.js实现表单验证详解
Jun 23 Javascript
Vue 父子组件的数据传递、修改和更新方法
Mar 01 Javascript
vue两个组件间值的传递或修改方式
Jul 04 Javascript
layui radio性别单选框赋值方法
Aug 15 Javascript
微信小程序实现顶部导航特效
Jan 28 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
php判断电脑访问、手机访问的例子
2014/05/10 PHP
yii中widget的用法
2014/12/03 PHP
PHP简单实现冒泡排序的方法
2016/12/26 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
PHP如何获取Cookie并实现模拟登录
2020/07/16 PHP
Js sort排序使用方法
2011/10/17 Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
2012/12/27 Javascript
JavaScript函数定义的常见注意事项小结
2014/09/16 Javascript
javascript解析json实例详解
2014/11/05 Javascript
javascript常用方法汇总
2014/12/02 Javascript
jquery实现定时自动轮播特效
2015/12/10 Javascript
jquery实现图片上传前本地预览功能
2016/05/10 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
Javascript基于jQuery UI实现选中区域拖拽效果
2016/11/25 Javascript
浅谈JavaScript的函数及作用域
2016/12/30 Javascript
基于require.js的使用(实例讲解)
2017/09/07 Javascript
全站最详细的Vuex教程
2018/04/13 Javascript
js中对象与对象创建方法的各种方法
2019/02/27 Javascript
Python读写Excel文件方法介绍
2014/11/22 Python
Python学习小技巧之列表项的排序
2017/05/20 Python
Python中类的初始化特殊方法
2017/12/01 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
python 自动批量打开网页的示例
2019/02/21 Python
Django项目中使用JWT的实现代码
2019/11/04 Python
Python如何使用字符打印照片
2020/01/03 Python
工程造价与财务管理专业应届生求职信
2013/10/06 职场文书
高中生自我鉴定范文
2013/10/30 职场文书
仓库管理专业个人自我评价范文
2013/11/11 职场文书
幼儿教师培训感言
2014/03/08 职场文书
党支部公开承诺书
2014/03/28 职场文书
作风大整顿心得体会
2014/09/10 职场文书
2014预防青少年违法犯罪工作总结
2014/12/10 职场文书
个人委托书范文
2015/01/28 职场文书
刘胡兰观后感
2015/06/16 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
MySQL数据库查询之多表查询总结
2022/08/05 MySQL