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

pgo*_*etz 5 javascript functional-programming naming-conventions

我一直在重读Spencer Tipping 十分钟内出色的Javascript,但对于我的生活,我无法弄清楚这个使用惰性作用域创建语法宏的例子:

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)
Run Code Online (Sandbox Code Playgroud)

特别是,

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

小智 5

那段代码吓到我了.它应该完全不被使用.(除非有一些真正令人信服的理由这样做,我不知道有任何1 2).另外,有没有 "函数式编程"在上面的代码演示,排除可能使用了回调.但是,即使是C也可以做到这一点,因为没有关闭.

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

$0$1被取代arguments[0]arguments[1],分别为(记住这是一个文本替换的功能"字符串"值!).它可以在没有"宏"的情况下手动输入:

function () { return arguments[0] + arguments[1] }
Run Code Online (Sandbox Code Playgroud)

或者我会做什么:

function (a,b) { return a + b }
Run Code Online (Sandbox Code Playgroud)

剩下的(Function.toStringeval(functionStr))是无意义的,以支持依赖于:"宏"的东西:Function -> codeString -> alteredCodeString -> Function.

此代码需要一个工作 Function.toString "因为它是源",能发出.我不确定IE何时开始支持这个,但它似乎在IE9中工作.


1这是一个小小的谎言,但是我使用这种方法的唯一地方是在侧边栏小工具中涉及IE,当弹出撤销时DOM可能"过早卸载",而另一个则试图在另一个中调用一个函数window上下文.一个全面的混乱局面..

2功能的JavaScript库显示多少"宏观魔法"可以做到没有 eval.


Wya*_*son 5

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

  1. f被定义为一种占位符函数.它似乎是真正的 宏观本身; 数值变量在被评估时将被替换g.它们充当了位置,可变参数,我们将在下面看到.
  2. g是魔术发生的地方:函数定义f被转换为字符串,宏定义f中的数值变量被替换为对索引参数的引用,因为定义中有许多数值变量f(因此正则表达式和调用to replace).刚使用下划线是因为我们不关心回调的第一个参数replace.
  3. 然后整个事情被eval编辑,一旦f基本上扩展到以下:

    function () { return arguments[0] + arguments[1] }
    
    Run Code Online (Sandbox Code Playgroud)

所以,它很简洁,因为您可以根据需要定义f尽可能多的位置数字参数:

var f = function() { return $0 + $1 + $2 }
Run Code Online (Sandbox Code Playgroud)

它会得到评估

function() { return arguments[0] + arguments[1] + arguments[2] }
Run Code Online (Sandbox Code Playgroud)

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