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 相关文章推荐
JS IE和FF兼容性问题汇总
Feb 09 Javascript
extjs DataReader、JsonReader、XmlReader的构造方法
Nov 07 Javascript
Jquery操作Select 简单方便 一个js插件搞定
Nov 12 Javascript
提交表单时执行func方法实现代码
Mar 17 Javascript
JavaScript下的时间格式处理函数Date.prototype.format
Jan 27 Javascript
深入理解JavaScript中的并行处理
Sep 22 Javascript
Angularjs cookie 操作实例详解
Sep 27 Javascript
vue router下的html5 history在iis服务器上的设置方法
Oct 18 Javascript
js中el表达式的使用和非空判断方法
Mar 28 Javascript
vue实现点击展开点击收起效果
Apr 27 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
May 06 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
Feb 20 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
用Zend Encode编写开发PHP程序
2010/02/21 PHP
完美实现GIF动画缩略图的php代码
2011/01/02 PHP
yii2.0数据库迁移教程【多个数据库同时同步数据】
2016/10/08 PHP
PHP使用curl制作简易百度搜索
2016/11/03 PHP
php图像处理函数imagecopyresampled用法详解
2016/12/02 PHP
身份证号码前六位所代表的省,市,区, 以及地区编码下载
2007/04/12 Javascript
IE无法设置短域名下Cookie
2010/09/23 Javascript
JavaScript Scoping and Hoisting 翻译
2012/07/03 Javascript
js 通用订单代码
2013/12/23 Javascript
详解jQuery向动态生成的内容添加事件响应jQuery live()方法
2015/11/02 Javascript
JavaScript 对象字面量讲解
2016/06/06 Javascript
JS 设置Cookie 有效期 检测cookie
2017/06/15 Javascript
JavaScript实现三级联动菜单实例代码
2017/06/26 Javascript
vue事件修饰符和按键修饰符用法总结
2017/07/25 Javascript
Vue使用localStorage存储数据的方法
2019/05/27 Javascript
JavaScript仿京东秒杀倒计时
2020/03/17 Javascript
JavaScript实现雪花飘落效果
2020/12/27 Javascript
[02:29]DOTA2英雄基础教程 陈
2013/12/17 DOTA
python实现ip查询示例
2014/03/26 Python
Python数据分析之如何利用pandas查询数据示例代码
2017/09/01 Python
Python列表(list)所有元素的同一操作解析
2019/08/01 Python
pandas 选取行和列数据的方法详解
2019/08/08 Python
centos+nginx+uwsgi+Django实现IP+port访问服务器
2019/11/15 Python
Python Django2 model 查询介绍(条件、范围、模糊查询)
2020/03/16 Python
Django数据库操作之save与update的使用
2020/04/01 Python
CSS3之transition实现下划线的示例代码
2018/05/30 HTML / CSS
HTML5 常用语法一览(列举不支持的属性)
2010/01/26 HTML / CSS
我的动漫时代的创业计划书范文
2014/01/27 职场文书
厨房管理计划书
2014/04/27 职场文书
2014教师个人自我评价范文
2014/09/13 职场文书
县委班子四风对照检查材料思想汇报
2014/09/29 职场文书
小学生思想品德评语
2014/12/31 职场文书
求职导师推荐信范文
2015/03/27 职场文书
2015年党员个人工作总结
2015/05/13 职场文书
Django基础CBV装饰器和中间件
2022/03/22 Python
xhunter1.sys可以删除嘛? win11提示xhunter1.sys驱动不兼容解决办法
2022/09/23 数码科技