[改进]还是那个让JavaScript具有(类似)Lambda表达式编程能力

在发了博文之后,我又花了一些时间尝试解决这个问题……经过几次尝试之后,我找到了另一种pattern,括号并不再是必要的了:

view sourceprint?
01 eval(function () {

02 var s = '', ww = [v] > (s += v);

03 var ws = [n] > ww(' <A href="#">(' + n + ')</A> ');

04

05 pnView3(14, [n] > ww(' [' + n + '] '),

06 1, 37,

07 ws, [] > ww(' ... '),

08 2, 1

09 );

10

11 document.write(s);

12 } .lamda0());


不过,由于运算符优先级的关系,比较、门、赋值等运算符仍然不能直接写在(伪)Lambda表达式中。

也就是说

view sourceprint?
1 function(a, b){ a == b }
仍然需要写成

view sourceprint?
1 [a, b] > (a == b)


另外,选择的pattern本身是具有实际效果的——当把一个数组和另一样东西进行比较的时候,脚本引擎会先尝试把两边都转化成数值,如果不成功就转化成字符串再比较。

不过我想正常情况下应该很少有人会拿数组跟别的东西这么比——所以甚至不需要主动去避免,只要用不到(伪)Lambda表达式的时候不特意去这样用就没问题了。



新的实现代码如下:

view sourceprint?
01 /*!

02 L-amda "a-Lambda", a module provides Alternate "Lambda" style programming ability for JavaScript.

03 Created By NanaLich. 2010-09-10

04 This module is published under WTFPL v2, so you just DO WHAT THE Fxxx YOU WANT TO with it.

05 */

06

07 !function () {

08 function attachEntry(o, a, m) {

09 var i, j, n;

10 o = [].concat(o);

11

12 while (i = o.shift()) {

13 for (j in a) {

14 if (!i[n = a[j]]) i[n] = m;

15 }

16 }

17 }

18

19 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;

20 var xy = /[\n\r),;\]}]|$/.source;

21

22 function rxClone(rx) {

23 return new RegExp(rx.source, (rx.global ? 'g' : '') + (rx.ignoreCase ? 'i' : '') + (rx.multiline ? 'm' : ''));

24 }

25 attachEntry(RegExp, ['clone'], rxClone);

26 attachEntry(RegExp.prototype, ['clone'], function () { return rxClone(this); });

27

28 function translateLambda(s) {

29 var m, l = 0, r = '', x = xx.clone(); // 由于firefox、safari等浏览器对全局匹配正则表达式有过度的优化,所以这里采用一种迂回的办法创建不重复的正则表达式实例

30

31 while (m = x.exec(s)) {

32 var h = m[0];

33

34 switch (h.charAt(0)) { // 判断期待的语法成分

35 case '$': // 函数传参

36 case ')':

37 case ']':

38 case '"': // 匹配到了字符串

39 case "'":

40 continue; // 以上皆跳过

41 }

42

43 var p, q, t, k = m[4].length, y = new RegExp(k ? '\\)' : xy, 'g');

44

45 r += s.substring(l, p = m.index); // 在结果字符串上附加之前余留的内容

46 y.lastIndex = l = p + h.length; // 从伪运算符之后开始寻找右括号或者其它符号

47

48 while (q = y.exec(s)) {

49 q = q.index;

50 try {

51 t = 'return(' + s.substring(l, q) + ');';

52 new Function(t); // 语法测试

53

54 r += m[1] + 'function(' + m[2] + '){ ' + translateLambda(t) + ' }'; // 翻译里面的内容

55

56 x.lastIndex = l = q + k; // 下一次查找从当前边界之后开始

57

58 break;

59 } catch (ex) { }

60 }

61 if (!q) l = p; // 说明找不到右括号或者有效的代码,直接附加所有匹配的内容

62 }

63

64 try {

65 r += s.substr(l);

66

67 new Function(r); // 语法测试

68 return r;

69 } catch (ex) { // 失败,返回原文

70 return s;

71 }

72 };

73

74 var lamdaAliases = ["translateLambda", "lambda", "lamda"];

75 attachEntry(String, lamdaAliases, translateLambda);

76 attachEntry(String.prototype, lamdaAliases, function () { return translateLambda(this); });

77

78 var funPrototype = Function.prototype;

79 attachEntry(Function, lamdaAliases, function (func) { return translateLambda('0,' + func); });

80 attachEntry(funPrototype, lamdaAliases, function () { return translateLambda('0,' + this); });

81

82 var lamda0aliases = ['lambdaInit', 'lambda0', 'lamda0'];

83 attachEntry(Function, lamda0aliases, function (func) { return translateLambda('!' + func + '()'); });

84 attachEntry(funPrototype, lamda0aliases, function () { return translateLambda('!' + this + '()'); });

85 } ();
这次为函数增加了专门的方法,去掉了之前蹩足的判断、也增加了新方法稍微简化调用过程;

修正了有额外空格时无法判断期望语法成分的BUG。



另外由于Codeplex再次抽疯,这次还是没有下载。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值