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 相关文章推荐
formValidator3.3的ajaxValidator一些异常分析
Jul 12 Javascript
基于jQuery的计算文本框字数的代码
Jun 06 Javascript
JavaScript初学者应注意的七个细节详细介绍
Dec 27 Javascript
jQuery中slideUp 和 slideDown 的点击事件
Feb 26 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
Feb 21 Javascript
Function.prototype.apply()与Function.prototype.call()小结
Apr 27 Javascript
Javascript中的迭代、归并方法详解
Jun 14 Javascript
前端JS面试中常见的算法问题总结
Dec 23 Javascript
JS实现求数组起始项到终止项之和的方法【基于数组扩展函数】
Jun 13 Javascript
JavaScript之创意时钟项目(实例讲解)
Oct 23 Javascript
Vue组件中的data必须是一个function的原因浅析
Sep 03 Javascript
vue-router权限控制(简单方式)
Oct 29 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 无限分类的树类代码
2009/12/03 PHP
Zend Framework动作控制器用法示例
2016/12/09 PHP
PHP程序员必须知道的两种日志实例分析
2020/05/14 PHP
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
2012/08/22 Javascript
innerHTML,outerHTML,innerText,outerText的用法及区别解析
2013/12/16 Javascript
js基于setTimeout与setInterval实现多线程
2016/06/17 Javascript
Summernote实现图片上传功能的简单方法
2016/07/11 Javascript
Node.js的Mongodb使用实例
2016/12/30 Javascript
jQuery编写设置和获取颜色的插件
2017/01/09 Javascript
vue上传图片组件编写代码
2017/07/26 Javascript
深入理解Node module模块
2018/03/26 Javascript
Angular路由ui-router配置详解
2018/08/01 Javascript
vue-cli安装使用流程步骤详解
2018/11/08 Javascript
Angular+Ionic使用queryParams实现跳转页传值的方法
2020/09/05 Javascript
Selenium执行JavaScript脚本的方法示例
2020/12/31 Javascript
跟老齐学Python之有容乃大的list(2)
2014/09/15 Python
Python性能优化的20条建议
2014/10/25 Python
Python中数字以及算数运算符的相关使用
2015/10/12 Python
python实现类之间的方法互相调用
2018/04/29 Python
Python3实现的字典、列表和json对象互转功能示例
2018/05/22 Python
Python使用jsonpath-rw模块处理Json对象操作示例
2018/07/31 Python
python爱心表白 每天都是浪漫七夕!
2018/08/18 Python
python中单例常用的几种实现方法总结
2018/10/13 Python
python实现同一局域网下传输图片
2020/03/20 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
2020/05/29 Python
音频处理 windows10下python三方库librosa安装教程
2020/06/20 Python
Python改变对象的字符串显示的方法
2020/08/01 Python
浅析CSS3中鲜为人知的属性:-webkit-tap-highlight-color
2017/01/12 HTML / CSS
网络工程系信息安全技术专业大学生求职信
2013/10/22 职场文书
房地产开发项目建议书
2014/05/16 职场文书
钱学森观后感
2015/06/04 职场文书
边城读书笔记
2015/06/29 职场文书
复活读书笔记
2015/06/29 职场文书
生日寿星公答谢词
2015/09/29 职场文书
低端且暴利的线上线下创业项目分享
2019/09/03 职场文书
JavaScript文档对象模型DOM
2021/11/20 Javascript