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异步编程的4种方法让你写出更出色的程序
Jan 17 Javascript
js实现点小图看大图效果的思路及示例代码
Oct 28 Javascript
禁止iframe脚本弹出的窗口覆盖了父窗口的方法
Sep 06 Javascript
纯js模拟div层弹性运动的方法
Jul 27 Javascript
快速学习AngularJs HTTP响应拦截器
Dec 31 Javascript
js内置对象处理_打印学生成绩单的简单实现
Sep 24 Javascript
微信小程序 教程之WXSS
Oct 18 Javascript
Javascript别踩白块儿(钢琴块儿)小游戏实现代码
Jul 20 Javascript
Angularjs中的验证input输入框只能输入数字和小数点的写法(推荐)
Aug 16 Javascript
JS随机数产生代码分享
Feb 24 Javascript
node使用Mongoose类库实现简单的增删改查
Nov 08 Javascript
Javascript文本框脚本实现方法解析
Oct 30 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 已经成熟
2006/12/04 PHP
php中使用session防止用户非法登录后台的方法
2015/01/27 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
2017/02/17 PHP
一个JQuery写的点击上下滚动的小例子
2011/08/27 Javascript
JS获取浏览器版本及名称实现函数
2013/04/02 Javascript
javascript中动态加载js文件多种解决办法总结
2013/11/15 Javascript
jquery浏览器滚动加载技术实现方案
2014/06/03 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
jQuery联动日历的实例解析
2016/12/02 Javascript
vue.js指令v-model实现方法
2016/12/05 Javascript
JavaScript实现多栏目切换效果
2016/12/12 Javascript
JS定时检测任务任务完成后执行下一步的解决办法
2016/12/22 Javascript
微信小程序 高德地图SDK详解及简单实例(源码下载)
2017/01/11 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
vuejs父子组件之间数据交互详解
2017/08/09 Javascript
js 原生判断内容区域是否滚动到底部的实例代码
2017/11/15 Javascript
详解Vue.js在页面加载时执行某个方法
2018/11/20 Javascript
JS用最简单的方法实现四舍五入
2019/08/27 Javascript
使用layer模态框给新页面传值的方法
2019/09/27 Javascript
JavaScript使用百度ECharts插件绘制饼图操作示例
2019/11/26 Javascript
JavaScript实现随机点名程序
2020/03/25 Javascript
[02:15]2015国际邀请赛选手档案IG.Ferrari 430
2015/07/30 DOTA
零基础写python爬虫之爬虫的定义及URL构成
2014/11/04 Python
分享一下Python 开发者节省时间的10个方法
2015/10/02 Python
使用Python内置的模块与函数进行不同进制的数的转换
2016/03/12 Python
Django接受前端数据的几种方法总结
2016/11/04 Python
Python(Django)项目与Apache的管理交互的方法
2018/05/16 Python
python IDLE添加行号显示教程
2020/04/25 Python
DVF官方网站:美国时装界尊尚品牌
2017/08/29 全球购物
Manduka官网:瑜伽垫、瑜伽毛巾和服装
2018/07/02 全球购物
英国领先的在线礼品店:Getting Personal
2019/09/24 全球购物
Java如何格式化日期
2012/08/07 面试题
申论倡议书范文
2014/05/13 职场文书
2014年个人工作总结模板
2014/12/15 职场文书
代码解析React中setState同步和异步问题
2021/06/03 Javascript
python可视化之颜色映射详解
2021/09/15 Python