19

我对 javascript 的深入研究越多,我就越会考虑某些设计决策和鼓励实践的后果。在这种情况下,我正在观察匿名函数,这个特性不仅是 JavaScript 提供的,而且我看到它被广泛使用。

我想我们都可以同意以下事实:

  • 人类的大脑不会处理超过 7 加减两个实体(米勒定律
  • 深缩进被认为是不好的编程习惯,如果缩进超过三个或四个级别,通常会指出设计问题。这扩展到嵌套实体,它在 python Zen 条目“Flat is better than nested”中得到了很好的呈现。
  • 有一个函数名的想法既是为了参考,也是为了便于记录它所执行的任务。我们知道或者可以期待一个名为 removeListEntry() 的函数的作用。自记录、清晰的代码对于调试和可读性很重要。

虽然匿名函数似乎是一个非常好的特性,但它的使用导致了深度嵌套的代码设计。代码写得很快,但读起来很困难。与其被迫为功能发明一个命名上下文,并扁平化你的可调用对象层次结构,它鼓励“深入一层”,推动你的大脑堆栈并迅速溢出 7 +/- 2 规则。Alan Cooper 的“ About Face ”中表达了类似的概念,粗略地引用了“人们不了解等级制度”。作为程序员,我们确实了解层次结构,但我们的生物学仍然限制了我们对深层嵌套的理解。

在这一点上,我想听听你的意见。匿名函数是否应该被认为是有害的,一种明显闪亮的语法糖,我们后来发现它是盐,甚至是老鼠药?

CW,因为没有正确的答案。

4

8 回答 8

16

在我看来,您面临的问题不是匿名函数,而是不愿意将功能分解为有用且可重用的单元。这很有趣,因为在具有一流函数(以及必然是匿名函数)的语言中重用功能比在没有一流函数的语言中更容易。

如果您在代码中看到很多深度嵌套的匿名函数,我建议可能有很多通用功能可以分解为命名的高阶函数(即获取或返回(“构建”)其他函数的函数)功能)。如果经常使用它们,即使是现有函数的“简单”转换也应该命名。这只是 DRY 原则。

于 2009-12-25T07:31:48.917 回答
8

匿名函数在功能上更有用,而不是在可读性上有害。我认为如果你的代码格式足够好,你应该没有问题。我没有问题,而且我确定我不能处理 7 个元素,更不用说 7 + 2 了 :)

于 2009-12-25T05:07:10.073 回答
4

实际上,层次结构有助于克服 7+/-2 规则,就像 OOP 一样。当您编写或阅读一个类时,您阅读的是它的内容而不是任何外部代码,因此您正在处理相对较小部分的实体。当您查看类层次结构时,您不会查看它们的内部,这意味着您再次处理少量实体。

如果嵌套函数为真,则相同。通过将代码分成多个层次结构级别,您可以使每个级别保持足够小以供人脑理解。

闭包(或匿名函数)只是有助于将您的代码分解成与 OOP 略有不同的方式,但它们并没有真正创建任何层次结构。它们在这里帮助您在其他代码块的上下文中执行您的代码。在 C++ 或 Java 中,您必须为此创建一个类,在 JavaScript 函数中就足够了。当然,独立类更容易理解,因为人类更容易将其视为独立块。函数的大小似乎要小得多,大脑有时认为它可以理解它并同时围绕它编写代码,这通常是一个坏主意。但是你可以训练你的大脑不要那样做:)

所以不,我不认为匿名函数是有害的,你只需要学会处理它们,就像你学会处理类一样。

于 2009-12-25T06:01:15.330 回答
3

有趣的是,JavaScript 可以让你命名“匿名”函数:

function f(x) {
   return function add(y) {
        return x+y;
   };
}
于 2009-12-26T01:18:34.290 回答
2

我认为闭包有巨大的好处,不容忽视。例如,Apple 利用 GCD 的“块”(C 的闭包)来提供非常简单的多线程 - 您不需要设置上下文结构,并且可以通过名称引用变量,因为它们在范围内。

我认为 Javascript 的一个更大问题是它没有块范围(在这种情况下,块指的是大括号中的代码,如 if 语句)。这可能会导致巨大的复杂性,迫使程序员使用不必要的闭包来绕过这个 Javascript 设计限制。

于 2009-12-25T05:05:41.240 回答
0

我还认为匿名函数(在最新的语言中通常称为闭包)有很大的好处,并且通常使代码更具可读性和更短。当我不得不使用 Java(闭包不是一流的语言特性)时,有时我会变得非常疯狂。

如果缩进和太多封装的函数变量是问题,那么您应该重构代码以使其更具模块化和可读性。

关于 java 脚本,我认为函数变量看起来很丑陋并且使代码混乱(封装的 function(...){} 字符串使 java 脚本代码通常不那么可读)。例如,我更喜欢 groovy 的闭包语法('{}' 和 '->' 字符)。

于 2009-12-26T00:36:40.237 回答
0

如果没有名称就无法理解函数,则名称可能太长。使用注释来解释神秘代码,不要依赖名称。

于 2009-12-26T04:07:44.420 回答
-2

谁提出了要求函数绑定到标识符的想法,这对每个程序员都是一种伤害。如果你从来没有做过函数式编程,而且你不熟悉和不习惯函数是一等值,那么你就不是一个真正的程序员。

事实上,为了反驳你自己的论点,我什至认为绑定到(全局)名称的函数是有害的!查看Crockford 关于私人和公共成员的文章并了解更多信息。

于 2009-12-25T06:24:45.237 回答