在函数调用中“使用严格”和命名参数

Posted

技术标签:

【中文标题】在函数调用中“使用严格”和命名参数【英文标题】:"use strict" and naming arguments in function calls 【发布时间】:2017-11-25 10:02:19 【问题描述】:

一位同事建议我将"use strict"; 添加到我的 JS 代码的顶部,以突出显示我的定义中的任何空白和潜在的引用错误等。我对此非常满意,因为它已经确定了几段可能有一直是个问题。

但是,另一位同事建议我,在调用带有多个参数的函数时,按照指定的参数命名参数会很有帮助,尤其是当它像一堆布尔值时。为了说明,这里有几个函数调用:

logData(data, target, preserveLog=true, changeClass=false, wrapLine=false);

...比:

logData(data, target, true, false, false);

但是"use strict"; 讨厌这个。在我完成此操作的任何地方,我都会在控制台中收到参考错误。正如预期的那样,它仍然可以正常运行,但是现在控制台中充斥着所有这些明显未定义的引用。

有谁知道是否有办法解决这个问题,这样我就可以保持我的同事欣赏的编码约定,还是我必须停止使用 "use strict"; 或检查我的所有代码并删除参数的名称?

谢谢。

【问题讨论】:

好吧,严格模式是正确的。这是一种可怕的做法。您到处都在将值泄漏到全局变量中。不要那样做。 如果你想使用“命名参数”,pass objects. @Bergi 谢谢,我可能会更改一些较长的调用来获取对象。 @Emissary 我相信您知道 IntelliSense 并非始终对每个工作环境中的每个人都可用,而且它当然不能成为编写不可读代码的借口。 在这里讨论使用对象的 ES6 调用约定是否合理? 【参考方案1】:

但是,另一位同事告诉我,在调用带有多个参数的函数时,按照指定的参数命名参数会很有帮助,尤其是当它像一堆布尔值时。

这是一个糟糕的建议!

javascript 实际上并不支持以这种方式通过名称传递参数。您“按名称”传递的每个参数实际上都被视为对具有该名称的全局变量的赋值,"use strict" 正确地将其识别为错误。

如果您想更清楚地知道要传递的值,请将值分配给真正的局部变量并传递它们,例如

var preserveLog = true;
var changeClass = false;
var wrapLine = false;
logData(data, target, preserveLog, changeClass, wrapLine);

如果你真的想继续使用原来的模式,你甚至可以在函数调用中为这些变量赋值,只要你先将它们声明为局部变量:

var preserveLog, changeClass, wrapLine;
logData(data, target, preserveLog=true, changeClass=false, wrapLine=false);

(向dav_i 致敬this answer, which I based my recommendation off of。)

【讨论】:

谢谢 - 公平地说,我认为他指的是 C#。我最近才被转移到一个 JavaScript 项目中,并假设我在 C# 中学到的东西会在一定程度上延续下去。在这种情况下,我想。 使用局部变量名有助于记住参数的含义,但我们不能忘记它仍然是一个位置参数。【参考方案2】:

在 ES6 中,你仍然没有命名参数,但你有第二好的东西,那就是 Object destructuring assignment。

这允许我们传递看似命名的参数,但实际上只是一个从未直接使用的对象的解构对象属性。

在您提供的示例的上下文中,它看起来像这样:

logData(data, target, preserveLog:true, changeClass:false, wrapLine:false);

其中函数定义为:

function logData(data, target, preserveLog, changeClass, wrapLine)  ... 

我已经看到很多库在 ES6 可用的情况下更喜欢这种调用约定,而且它也非常方便,因为参数的顺序也不再重要了。

【讨论】:

以上是关于在函数调用中“使用严格”和命名参数的主要内容,如果未能解决你的问题,请参考以下文章

Perl 是不是支持函数调用中的命名参数?

如何在 C++ 中使用命名参数

JavaScript:未命名函数的参数

在Python中命名参数

将命名参数传递给 Django 模板中的函数

使用可变参数但使用命名参数调用函数的 Scala 语法是啥?