十分钟内的Javascript:这个示例代码说明了懒惰的范围是怎么回事?

时间:2012-06-26 21:25:06

标签: javascript functional-programming naming-conventions

我一直在重新阅读Spencer Tipping的优秀Javascript in Ten Minutes,但对于我的生活,我无法弄清楚这个使用惰性作用域来创建句法宏的例子:

var f = function () {return $0 + $1};  
var g = eval (f.toString ().replace (/\$(\d+)/g,  
           function (_, digits) {return 'arguments[' + digits + ']'}));  
g(5,6); // => 11 (except on IE)

特别是

  1. $ 0和$ 1正在被一个函数定义所取代 - 函数如何被评估? (大概是通过eval(),但我没有看到这个。)
  2. 函数中单个下划线参数的目的是什么 - 如果我把它取出,代码就不再有用了。据推测它只是一个占位符,但为什么需要呢?

2 个答案:

答案 0 :(得分:5)

那段代码吓到我了。它应该完全不被使用。 (除非有一些非常有说服力的理由;我不知道任何 1 2 。)此外,还有上面的代码中没有显示“函数式编程”,不包括可能使用回调。但是,即使是C也可以做到这一点,因为没有关闭。

_只是一个有效的标识符(例如foo_foo$0)。这里用于“不关心”(该值是整个匹配文本的值,因为该函数是RegExp匹配的“回调”)。

$0$1分别由arguments[0]arguments[1]取代(请记住,这是函数的文本替换)到字符串“价值!)。它可以在没有“宏”的情况下手动输入:

function () { return arguments[0] + arguments[1] }

或者我会做的事情:

function (a,b) { return a + b }

其余的(Function.toStringeval(functionStr))无意义支持依赖于Function -> codeString -> alteredCodeString -> Function的“宏”内容。

此代码需要正常工作 Function.toString才能发出“源本身”。我不确定IE何时开始支持此功能,但它似乎可以在IE9中运行。


1 这是一个小小的谎言,但我使用这种方法的唯一的地方涉及在侧边栏小工具中的IE,其中DOM可能“过早卸载”当一个弹出窗口被撤回时以及其他一些混乱,试图在另一个window上下文中调用一个函数。一个混乱的局面..

2 Functional JavaScript Library显示可以在没有 eval的情况下完成“宏魔术”。

答案 1 :(得分:5)

我同意 pst ,这段代码非常可怕。这太可怕了 可读性。但它很整洁:

  1. f被定义为一种占位符函数。这似乎是实际的 本身;数值变量在评估时将被替换 进入g。它们充当了位置,可变参数,我们将在下面看到。
  2. g是神奇发生的地方:f的函数定义被转换 到一个字符串,宏定义f中的数字变量是 替换为对多个数字的索引参数的引用 变量存在于f的定义中(因此是正则表达式) 并致电replace)。使用下划线是因为我们不在乎 关于replace回调的第一个参数。
  3. 一旦eval基本上扩展到了f,整个事情就会被function () { return arguments[0] + arguments[1] } 编辑 以下内容:

    f
  4. 所以,它很简洁,因为您可以使用尽可能多的位置数字来定义var f = function() { return $0 + $1 + $2 } 你想要的论点:

    function() { return arguments[0] + arguments[1] + arguments[2] }
    

    并且它会被评估为

    {{1}}

    整洁,但无用,可以说是危险的,不切实际且难以阅读。 我可能不会使用它。