[乍看上去缺点比优点多的无聊创作]让JavaScript拥有(类似)Lambda表达式编程能力
2010-09-10 09:56
288 查看
在前几天的博文中我发布了一个可以自定义页码呈现方式的组件,有C#和JavaScript两个版本。
但是我后来也跟人说,因为接受的参数太多,所以如果不把智能提示写得很清楚的话,连我自己都常常搞不清楚该怎么用。
不过,接受参数多,除了容易弄错用法以外,还会产生另一个问题,这也是我编写出今天发布的这个东西的原因。
来看一下JS版的页码呈现组件的完全版函数签名:
当我在网页中测试这个组件的时候我就觉得自己非常想念C#中的Lambda表达式——虽然有些人、有些JS框架会把匿名函数称作“Lambda表达式”,但其实那只相当于C#中的“匿名委托/函数”,而Lambda的(表面)特征是使用简短的语法模式来反映一个(回调)函数/过程(或者说动作)的逻辑,而不被“delegate”或者别的什么关键字分散精力。
出于这样的原因,我编写了这个可以转译JS代码、把一种特定的模式(pattern)翻译成函数定义的模块。
在使用这个模块以后,前面的那个调用可以变成这个样子:
模块的完整代码如下:
昨天codeplex抽疯,代码和release上传总出错。再考虑到这个模块的使用场合比较有限,不适合缺乏JavaScript经验的人使用,所以不另外提供源代码打包下载——有需要的话请直接从文中复制。
但是我后来也跟人说,因为接受的参数太多,所以如果不把智能提示写得很清楚的话,连我自己都常常搞不清楚该怎么用。
不过,接受参数多,除了容易弄错用法以外,还会产生另一个问题,这也是我编写出今天发布的这个东西的原因。
来看一下JS版的页码呈现组件的完全版函数签名:
function ww(s) { document.write(s); } function ws(n) { ww(' (' + n + ') '); } pnView(14, function (n) { ww(' [' + n + '] ') }, 1, 27, function (n) { ww('|< ' + n + ' '); }, function (n) { ww(' ' + n + ' >|'); }, 2, ws, 1, function () { ww(' ... '); }, 2, 2, ws, ws );
当我在网页中测试这个组件的时候我就觉得自己非常想念C#中的Lambda表达式——虽然有些人、有些JS框架会把匿名函数称作“Lambda表达式”,但其实那只相当于C#中的“匿名委托/函数”,而Lambda的(表面)特征是使用简短的语法模式来反映一个(回调)函数/过程(或者说动作)的逻辑,而不被“delegate”或者别的什么关键字分散精力。
出于这样的原因,我编写了这个可以转译JS代码、把一种特定的模式(pattern)翻译成函数定义的模块。
在使用这个模块以后,前面的那个调用可以变成这个样子:
(' + n + ') ')); pnView(14, (n, ww(' [' + n + '] ')), 1, 27, (n, ww('|< ' + n + ' ')), (n, ww(' ' + n + ' >|')), 2, ws, 1, (0, ww(' ... ')), 2, 2, ws, ws ); }.lamda())();
模块的完整代码如下:
如果和C#中的Lambda表达式相比的话,我的这个模块还是有很多不足的,不过现在这个样子已经让我很满意了,至少我不用再写太多的“function”了。 简单来说,这个模块的规格特性是这样的—— 优点: 减少编写代码时“function”的出现次数; 使用可以在一般的JavaScript编辑器中正常编辑的语法模式(pattern),直接写在函数体中不会导致语法错误。 局限性: 在任何时候使用这个模块都必须调用转译方法(“translateLambda”、“lambda”或者“lamda”)和eval函数,无法省略; 如果存在一个函数A,不可能通过对A进行处理来达到转译传递至A的参数的目的(也就是说a.lambda()或者类似的操作并不会让a((x, x * 2))等同于a(function(x){ return x * 2; })); 不能包含表达式之外的任何语句、不能包含使用“;”来分隔的多条语句。 缺点: 连续出现的括号可能会让代码变得难以理解; 任何编辑器都无法为Lambda表达式提供语法高亮; 存在错误地转译现有代码的可能性——这个模块选择进行匹配的模式是在正常的代码中没有实用价值、也通常不会出现的模式,如:(x, x * 2)等价于单纯的x * 2、(0, a.method())等价于单纯的a.method(),所以这个缺点影响到实际代码的可能性无限趋近于0。 以下是几种不当的用法: 使用这个模块并不会节省很多代码量的时候:本末倒置。eval(function(){ // 不仅没减少代码量,反而还增加了 window.onload = (0, alert('载入完成!')); }.lambda());
对接受参数的函数进行转译处理:之前已经提到过这种情况。eval("somefunction((x, x.toString(16)))".lamda()); // 失去了语法检查,可能在运行的时候产生意外
在(伪)Lambda中使用过多的操作,甚至多条语句:
在设计这个模块的时候我并没有找出可以使用多条语句且可以通过语法检查的模式(pattern),原因是在Lambda表达式中使用多条语句时,“function”、“return”等几个字符所增加的代码量通常是可以忽略的,这样去使用Lambda表达式本身就属于一种偏离了初衷的做法。(function(){ // 所有的代码都放在这里 })();
——而这种“大”闭包正好是使用本模块的最佳场合:
eval(function(){ // 括号前增加eval
// 所有的代码都放在这里
}.lamda())(); // 括号里增加.lamda()
昨天codeplex抽疯,代码和release上传总出错。再考虑到这个模块的使用场合比较有限,不适合缺乏JavaScript经验的人使用,所以不另外提供源代码打包下载——有需要的话请直接从文中复制。
相关文章推荐
- 让JavaScript拥有类似Lambda表达式编程能力的方法
- [改进]还是那个让JavaScript具有(类似)Lambda表达式编程能力
- 让JavaScript拥有类似Lambda表达式编程能力的方法
- JavaScript具有类似Lambda表达式编程能力的代码(改进版)
- JavaScript具有类似Lambda表达式编程能力的代码(改进版)
- javascript的优点和缺点
- javascript消除字符串两边空格的两种方式,面向对象和函数式编程。python oop在调用时候的优点
- JavaScript是一种弱类型语言,有什么优点和缺点
- nginx_lua 扩展让 nginx 拥有可编程能力
- javascript创建对象的7种模式(赋:优点+缺点分析)
- <<javascript 高效图形编程>>笔记
- javascript 高级编程之模拟类
- 应当避免的JavaScript编程问题
- 程序员:编程能力vs职业技能,哪个更重要
- [技巧] Javascript模块化编程(三):require.js的用法
- Web前端研发工程师编程能力飞升之路
- 读GI源码、学JS编程——Javascript动态加载技术。
- 什么才算是真正的编程能力
- WEB前端工程师编程能力成长之路2【转】
- JavaScript框架编程