不使用 JS 匿名函数理由
本文给大家分析了不使用js匿名函数的三大理由,JS匿名函数的作用是避免全局变量的污染以及函数名的冲突,关于js匿名函数的三大理由大家参考下本文
匿名函数的基本形式为(function(){...})();
前面的括号包含函数体,后面的括号就是给匿名函数传递参数并立即执行之
匿名函数的作用是避免全局变量的污染以及函数名的冲突
无论你在什么时候读代码,您都必须注意到匿名函数。有时它们被称为 lambda,有时是匿名函数,不管怎样,我认为他们是不好使用的。
如果你不知道匿名函数是什么,这里有一个引语:
匿名函数是一种在运行时动态声明的函数。它们之所以被称为匿名函数是因为不同于普通函数,它们并没有函数名 。 — Helen Emerson, Helephant.com
匿名函数形式如下:
function () { ... code ... } OR (args) => { ... code .. }
我今天尝试让大家理解通常情况下只有在绝对需要的情况下才使用匿名函数的想法。匿名函数不应该是首选,而且应该知道原因情况下使用。当理解这种想法之后,你的代码会变得更简洁,更容易维护,并且更容易跟踪bug。先从避免使用匿名函数的三个理由开始:
你写代码的时候, 无论你多么擅长敲代码, 总是会碰到错误。有时候,这些错误很容易被查出,有时候并不容易。
如果你知道这些错误来自哪里,那么错误很容易会被查出来。为了查出错误,我们使用这个被叫做堆栈轨迹的工具。如果你不了解 堆栈轨迹 ,goole给出了很棒的介绍。
假设现在有一个非常简单的工程:
function start () { (function middle () { (function end () { console.lg('test'); })() })() }
上面代码里面有一个非常愚蠢的错误,拼写错误(console.log)。在小工程里面,这个拼写错误不是什么大问题。 如果这是一个有非常多模块非常大的工程的一小段,问题就大了。假设这个愚蠢的错误不是你犯的,那么新来的初级工程师将会在他休假之前把这个错误提交到代码库!
现在,我们必须追查。 使用我们精心命名的函数, 我们得到如下的堆栈跟踪:
谢谢你命名你的函数 ,初级开发者们! 现在我们可以轻松地追踪到这个bug。
但是..一旦我们解决了这个问题, 就会发现 还有另一个bug。 这次是一位更资深的开发人员介绍的。这个人知道 lambdas
结果他们偶然发现了一个bug,我们的工作就是追踪它。
下面是代码:
(function () { (function () { (function () { console.lg('test'); })(); })(); })();
吃不吃惊,这名开发者也忘记了如何拼写console.log了!这也太巧合了吧!令人感到遗憾的是,他们都没有命名他们的函数。
那么控制台会输出什么呢?
好吧,我们至少还有行号,对吧?在这个例子中,看起来我们有大约7行代码。如果我们处理一大段代码会如何呢?比如一万行代码?行号的跨度如此之大该怎么办呢?如果代码被折叠后有没有一个代码地图文件,那么对行号的渲染是不是根本就是没有什么用了呢?
我想对这些问题的回答相当简单,答案就是:想这些会让你一整天都会过的相当糟心。
可读性
咦,我听说你还不信。你仍旧对你的匿名函数恋恋不舍,并且还从未发生过bug。那么我得向你道歉,你认为你的代码是完美的。让我们看看这个!
看看下面两段代码:
function initiate (arguments) { return new Promise((resolve, reject) => { try { if (arguments) { return resolve(true); } return resolve(false); } catch (e) { reject(e); } }); } initiate(true) .then(res => { if (res) { doSomethingElse(); } else { doSomething(); } ).catch(e => { logError(e.message); restartApp(); } );
这是一个非常不正常的例子,但是我相信你已经明白我要说什么 了。我们的方法返回了一个promise,我们用这个promise对象/方法处理不同可能的 响应。
你也许会认为几段代码读起来并不难,但我认为它们可以变得更好!
如果我们去掉所有的匿名函数会怎样呢?
function initiate (arguments) { return new Promise(checkForArguments); } function checkForArguments (resolve, reject) { try { if (arguments) { return resolve(true); } return resolve(false); } catch (e) { reject(e); } } function evaluateRes (res) { if (res) { doSomethingElse(); } else { doSomething(); } } function handleError (e) { logError(e.message); restartApp(); } initiate(true) .then(evaluateRes) .catch(handleError);
好,先讲清楚:这部分代码更长,但我认为其不仅仅是有更多的可读性!我们精心命名的函数与匿名函数不一样,只要我们一看到它们的名字就知道它们的功能是什么。这避免了在评估代码时的障碍。
这也有助于分清楚其中的关系。与创建一个方法、将其传递、然后运行逻辑不同,在第二个例子中的参数被给到了then,catch只是指向了发生所有事情的函数。
关于更具有可读性,我没有什么再能说服你的了。但是也许你还没被说服的话,我可以试一下最后的论据。
相关推荐:
以上是不使用 JS 匿名函数理由的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

Go语言提供了两种动态函数创建技术:closures和反射。closures允许访问闭包作用域内的变量,而反射可使用FuncOf函数创建新函数。这些技术在自定义HTTP路由器、实现高度可定制的系统和构建可插拔的组件方面非常有用。

在C++函数命名中,考虑参数顺序至关重要,可提高可读性、减少错误并促进重构。常见的参数顺序约定包括:动作-对象、对象-动作、语义意义和遵循标准库。最佳顺序取决于函数目的、参数类型、潜在混淆和语言惯例。

1、 SUM函数,用于对一列或一组单元格中的数字进行求和,例如:=SUM(A1:J10)。2、AVERAGE函数,用于计算一列或一组单元格中的数字的平均值,例如:=AVERAGE(A1:A10)。3、COUNT函数,用于计算一列或一组单元格中的数字或文本的数量,例如:=COUNT(A1:A10)4、IF函数,用于根据指定的条件进行逻辑判断,并返回相应的结果。

C++函数中默认参数的优点包括简化调用、增强可读性、避免错误。缺点是限制灵活性、命名限制。可变参数的优点包括无限灵活性、动态绑定。缺点包括复杂性更高、隐式类型转换、调试困难。

C++中的函数返回引用类型的好处包括:性能提升:引用传递避免了对象复制,从而节省了内存和时间。直接修改:调用方可以直接修改返回的引用对象,而无需重新赋值。代码简洁:引用传递简化了代码,无需额外的赋值操作。

自定义PHP函数与预定义函数的区别在于:作用域:自定义函数仅限于其定义范围,而预定义函数可在整个脚本中访问。定义方式:自定义函数使用function关键字定义,而预定义函数由PHP内核定义。参数传递:自定义函数接收参数,而预定义函数可能不需要参数。扩展性:自定义函数可以根据需要创建,而预定义函数是内置的且无法修改。

C++中的异常处理可通过定制异常类增强,提供特定错误消息、上下文信息以及根据错误类型执行自定义操作。定义继承自std::exception的异常类,提供特定的错误信息。使用throw关键字抛出定制异常。在try-catch块中使用dynamic_cast将捕获到的异常转换为定制异常类型。实战案例中,open_file函数抛出FileNotFoundException异常,捕捉并处理该异常可提供更具体的错误消息。
