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 相关文章推荐
[原创]网络复制内容时常用的正则+editplus
Nov 30 Javascript
面向对象的javascript(笔记)
Oct 06 Javascript
早该知道的7个JavaScript技巧
Mar 27 Javascript
jQuery前端框架easyui使用Dialog时bug处理
Dec 05 Javascript
javascript编写实用的省市选择器
Feb 12 Javascript
纯JS前端实现分页代码
Jun 21 Javascript
JS选取DOM元素的简单方法
Jul 08 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
Apr 11 Javascript
深究AngularJS之ui-router详解
Jun 13 Javascript
JS html事件冒泡和事件捕获操作示例
May 01 Javascript
ligerUI的ligerDialog关闭刷新的方法
Sep 27 Javascript
js禁止查看源文件屏蔽Ctrl+u/s、F12、右键等兼容IE火狐chrome
Oct 01 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获取浏览器信息类和客户端地理位置的2个方法
2014/04/24 PHP
Thinkphp 在api开发中异常返回依然是html的解决方式
2019/10/16 PHP
自适应高度框架 ----属个人收藏内容
2007/01/22 Javascript
javascript 面向对象编程 聊聊对象的事
2009/09/17 Javascript
jquery使用ColorBox弹出图片组浏览层实例演示
2013/03/14 Javascript
jQuery根据纬度经度查看地图处理程序
2013/05/08 Javascript
浅析jQuery中常用的元素查找方法总结
2013/07/04 Javascript
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
2013/11/22 Javascript
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
2015/03/04 Javascript
jquery判断至少有一个checkbox被选中的方法
2015/06/05 Javascript
Bootstrap每天必学之标签页(Tab)插件
2020/08/09 Javascript
vue弹窗消息组件的使用方法
2020/09/24 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
详解如何在vue项目中使用layui框架及采坑
2019/05/05 Javascript
深入学习JavaScript中的bom
2019/05/27 Javascript
jQuery操作事件完整实例分析
2020/01/10 jQuery
Vuex的各个模块封装的实现
2020/06/05 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
2020/06/19 Javascript
axios解决高并发的方法:axios.all()与axios.spread()的操作
2020/11/09 Javascript
JS算法教程之字符串去重与字符串反转
2020/12/15 Javascript
原生JavaScript实现幻灯片效果
2021/02/19 Javascript
[05:31]DOTA2英雄梦之声_第08期_莉娜
2014/06/23 DOTA
[02:58]魔廷新尊——痛苦女王至宝语音台词节选
2020/06/14 DOTA
Python正则表达式使用经典实例
2016/06/21 Python
python3 shelve模块的详解
2017/07/08 Python
使用openCV去除文字中乱入的线条实例
2020/06/02 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
任意存:BOXFUL
2018/05/21 全球购物
环境科学专业个人求职信
2013/09/26 职场文书
中专自我鉴定范文
2013/10/16 职场文书
企业办公室主任岗位职责
2014/02/19 职场文书
酒店员工培训方案
2014/06/02 职场文书
带刀到教室的检讨书
2014/10/04 职场文书
2014最新股权信托合同协议书
2014/11/18 职场文书
Python循环之while无限迭代
2022/04/30 Python